ابيثون فكر كيف تفكر كعامل حاسوب النسخة 2.0.17
فكر بايثون 2
فكر بايثون 3 فكر ابيثون كيف تفكر كعامل حاسوب النسخة 2.0.17 ألن داوين منشورات جرين يت نيدهام ماساشوستس ترمجة طارق زيد الكيالين
فكر بايثون 4 حقوق النرش 2012 ألن داوين منشورات جرين يت 9 شارع وشربن نيدهام 02492 MA يسمح ابلنسخ التوزيع و/ أو تعديل هذه الوثيقة حتت بنود Creative Commons Attribution-NonComercial 3.0 و املتوفرة عىل http://creativecommons.org/licenses/by-nc/3.0 Unported license الصيغة الاصلية لهذا الكتاب يه نص أصيل من. LATEX ترمجة نص الوسيةل اليت يعرض علهيا و ميكن حتويهل اىل تنس يقات أخرى و طباعته. نص الصيل لهذا الكتاب متوفرة من هذه تنتج LATEX كتاب تدريس غري معمتد عىل.http://www.thinkpython.com LATEX حقوق الرتمجة طارق زيد الكيالين This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. أرسل الاعرتاضات و التصحيح ان شئت اىل.kelany@hotmail.com
مقدمة التارخي العجيب لهذا الكتاب يف اكنون 1999 كنت أحرض لتدريس مدخل اىل الربجمة بلغة جافا. كنت قد در ست هذه املادة ثالث مرات من قبل و الحباط يمتلكين. اكن معدل الرسوب مرتفع جدا وحىت من جنح من الطالب مل يكن عىل املس توى املطلوب. احدى املشالك اليت لحظهتا اكنت خضامة الكتب و احتواهئا عىل الكثري من املعلومات غري الرضورية عالوة عىل فقرها يف ارشاد الطالب اىل كيفية الربجمة. لكها عانت من تأثري الباب املسحور: اكنت تبدأ سهةل مث تتواصل تدرجييا لكن عند مرحةل معينة حنو الفصل اخلامس تهنار الارضية حتت اقدام الطلبة. مك املعلومات يزتايد برسعة و أضطر لكامل الفصل حماول مللمة الفتات. قبل الفصل بأس بوعني قررت كتابة املادة بنفيس. أهدايف اكنت: ما قل و دل. أن يقرأ الطالب 10 صفحات أفضل من قراءة 50. احلذر عند استخدام الالفاظ. حاولت الابتعاد عن غريب الالكم. البناء التدرجيي. لتجنب الابواب املسحورة قسمت أصعب املواد اىل سلسةل من اخلطوات الصغرية. الرتكزي عىل الربجمة ل عىل لغة الربجمة. فضمنت الكتاب أقل ما ميكن من لغة جافا و تركت البايق. احتجت اىل عنوان و يف حلظة جتيل اخرتت: كيف تفكر كعامل حاسوب. اكنت النسخة الاوىل جلفة الا اهنا أمثرت. فقد قرأ الطالب املادة و اس توعبوها برسعة مما مسح يل ابس تخدام ابيق زمن الفصل يف رشح النقاط الصعب و تكل الاكرث ااثرة )و أكرث أمهية( اتراك الطالب يمترنون. أخرجت الكتاب حتت ترخيصGNU ترخيص املنشورات املانية اليت تسمح للمس تخدمني ابلنسخ و التعديل و توزيع الكتب. ما حدث اتليا اكن اجلزء الفضل. جف الكرن مدرس اثنوي من فرجينيا تبىن كتايب و ترمجه اىل ابيثون. أرسل ايل بنسخة من الرتمجة فس نحت يل الفرصة الاس تثنائية لتعمل ابيثون من كتايب أان!. و كجرين يت برس نرشت اول نسخة من ابيثون يف 2001. يف العام 2003 بدأت التدريس يف لكية أولن اكن عيل تدريس ابيثون للمرة الاوىل. صدمين الفرق بيهنا و بني جافا. قل ت معاانة الطالب تعلموا و معلوا أكرث عىل مشاريع أكرث ااثرة. خمترص احلديث... مزيدا من املرح. خالل التسع س نوات املاضية اس متريت بتطوير الكتاب أحصح الاخطاء أحسن بعض المثةل و أضيف املواد خصوصا الامترين. اكنت النتيجة هذا الكتاب بعنوان أقل خفامة " فكر ابيثون". بعض التغيريات اكنت:
vi فكر بايثون أضفت جزءا عن تصحيح الخطاءهناية لك فصل. ترشح هذه الاجزاء الاساليب العامة لجياد و جتنب البقات و حتذيرات عن الخطار اهلفية يف لغة ابيثون. أضفت متارين أكرث تراوحت بني حفوصات قصرية للتأكد من الاستيعاب اىل ما ميكن ان يرىق اىل مشاريع معتربة. أضفت سلسةل من املسائل العملية و أمثةل أطول مع متاريهنا و كذكل مناقشات. بعضها مبين عىل سواميب و هو برانمج جانيب كتبته لالس تخدام خالل حمارضايت. سواميب الامثةل و بعض احللول متوفرة من./ttinhht/p:niht/t:.tth تعمقت يف أساليب تطوير الربامج و مذاهب تصمميها الاساس ية. أضفت تذييالت عن التصحيح حتليل اخلوارزميات و ال " يو ام ال" مع " مليب". أمتىن أن تس متتع ابلعمل هبذا الكتاب و أن يساعدك يف تعمل كيف تربمج و كيف تفكر عىل الاقل بدرجة واحدة اعىل كام يفكر علامء احلاسوب. ألن داوين نيدهام ماساشوستس. ألن داوين أس تاذ علوم احلاسوب يف لكية فرانلكن و. أولن للهندسة. عرفان الشكر الجزيل لجف الكنر الذي ترجم كتابي عن جافا إلى بايثون ما جعل هذا المشروع ينطلق. و عرفني إلى ما اصبحت لغة البرمجة المفضلة عندي. الشكر أيضا لكرس مي ر الذي ساهم بعدة أقسام في "كيف تفكر كعالم حاسوب". الشكر لمؤسسة البرامج المجانية FSF و إلى التراخيص المجانية للوثائق GNU التين ساعدتا في جعل تعاوني مع جف و كرس ممكنا و لإلبداع العام Creative Commons على الرخصة التي استخدمها االن. الشكر للمحررين في لولو Lulu الذين عملوا على "كيف تفكر كعالم حاسوب". الشكر لكل الطلبة الذين عملوا بالنسخ األبكر من هذا الكتاب و كل المساهمين )في القائمة أدناه( الذين أرسلوا التصحيحات و االقتراحات.
vii فكر بايثون قائمة المساهمين أكثر من مئة من ثاقبي النظر و من القراء المفكرين أرسلوا مقترحاتهم و تصحيحاتهم خالل السنوات الماضية. مساهماتهم و حماسهم لهذا المشروع كانت دعما كبيرا. إن كان لديك اقتراح أو تصحيح فالرجاء أرساله إلى البريد feedback@thinkpython.com و إن قمت بتغيير ما بناءا على ما أرسلته سأضيف اسمك إلى قائمة المساهمين )إال إن أردت عدم االضافة(. إن ضم نت جزءا على االقل من العبارة التي يظهر فيها الخطأ ستسهل علي البحث. رقم الصفحة و القسم يفيد أيضا لكن ليس بسهولة البحث عن عبارة محددة. شكرا! لويد هف ألن أرسل تصحيحا على القسم 8.4. إيفون بويان أرسل تصحيحا لخطأ داللي في الفصل الخامس. فرد بريمر أرسل تصحيحا في القسم 2.1. يونا كوهن كتب نص بيرل لتحويل النص األصلي من التكس لهذا الكتاب إلى HTMLجميل. ميشيل كنلن أرسل تصحيحا قواعديا على الفصل الثاني و تحسينات على األسلوب في الفصل االول و هو من استهل النقاشات حول النواحي الفنية للمفس رات. بنوا جيرار أرسل تصحيحا لخطأ مضحك في القسم 5.6. كورتني جليسون و كاثرن سمث كتبا horsebet.py و الذي استخدم كدراسة حالة في نسخ سابقة لهذا الكتاب. برنامجهما متوفر االن على موقع الويب. لي هر أرسل من التصحيحات مما ال يتسع لذكرها المقام و لذا يجب أن يدرج كأحد المحررين الرئيسين لهذا المخطوط. جيمس كيلن طالب يستخدم هذا الكتاب و قد أرسل العديد من التصحيحات. ديفد كيرشو أصلح اقتران cattwice كان مكسورا في القسم 3.10 إدي الم أرسل العديد من التصحيحات على األقسام 1 2 و. 3 و أصلح أيضا Makefile بحيث تنشئ مؤشرا عندما تشغل ألول مرة و ساعدنا في تجهيز طريقة تسمية النسخ. مان-يونغ لي أرسل تصحيحا للمثال في القسم 2.4 ديفد مايو أوضح لنا بأن الكلمة unconsciously في الفصل األول يجب أن تستبدل ب. subconsciously كرس مكلون أرسل العديد من التصحيحات على االقسام 3.9 و 3.10 ماثيو جي مولتر كان مساهما دائما و قد أرسل العديد من التصحيحات و االقتراحات لهذا الكتاب. سيمون ديكون مانفورد أبلغنا عن تعريف إقتران نسيناه و أخطاء مطبعية عديدة في الفصل الثالث. و قد عثر أيضا على أخطاء في االقتران المزيدي في الفصل 13 جون اوزتس صحح تعريف القيمة المرتجعة في الفصل الثالث كفن باركس أرسل تعليقات قيمة و اقتراحات على كيفية رفع مستوى توزيع الكتاب. ديفد بول أرسل لنا عن خطأ مطبعي في قسم المعاني في الفصل االول و كذلك كلمات لطيفة كتشجيع. مشيل شمت أرسل تصحيح على فصل الملفات و االستثناءات روبن شو عين لنا مكان خطأ في القسم 13.1 حيث استخدم printtime في مثال بدون تعريفه. بول سليخ عثر على خطأ في الفصل 7 و بقة في نص بيرل ل يونا كوهن الذي يولد HTML من التكس كريغ تي سيندل يختبر المخطوط في دورة في جامعة درو. لقد ساهم بالعديد من االقتراحات القيمة و التصحيحات. إي ن تومس و طلبته يستخدمون المخطوط. هم أول من يختبر الفصول في النصف االخير من الكتاب و قد قدموا العديد من التصحيحات و االقتراحات. كيث فرهيدن أرسل تصحيحا على الفصل الثالث. بيتر وستنلي أعلمنا عن خطأ قائم منذ مدة في النص الالتيني المستخدم في الفصل 3. كرس ربل قام بالعديد من التصحيحات على النص البرمجي في الفل مدخالت و مخرجات الملفات و االستثناءات.
viii فكر بايثون موشي زدكة مساهمته قيمة لهذا المشروع. فباإلضافة إلى كتابة المسودة االولى لفصل القواميس قدم أرشادات قيمة منذ المراحل االولى لهذا الكتاب. كرستوف زو رشك ة أرسل العديد من التصحيحات و اقتراحات في التعليم و شرح الفرق بين gleich و. selble جيمس مي ر أرسل لنا دلوا ممتلئا من األخطاءاللفظية و المطبعية من ضمنها خطأين في قائمة العرفانات نفسها. هايدن م ك في التقط ما قد يصبح تناقض مشوش بين مثالين. هايدن أرنل هو من الفريق العالمي من المترجمين و يعمل على النسخة االسبانية من المخطوط. و قد عثر على عدة أخطاء في النسخة االنجليزية توحيد الحق و لكس بيرزني أنشا األشكال التوضيحية في الفصل االول و حسنا الكثير من االشكال االخرى د. ميشيل الزيتا التقط خطأ في الفصل 8 و أرسل بضعة اقتراحات مميزة حول التعليم و اقتراحات حول فيبوناشي وMaid Old اندي متشل التقط خطأ مطبعيا في الفصل االول و مثال مكسور في الفصل الثاني. كالن هارفي اقترح توضيحا في الفصل 7 و التقط بضعة أخطاء مطبعية. كرستفر بي سمث التقط عدة أخطاء مطبعية و ساعد في تحديث الكتاب ديفد هطشنز التقط خطأ مطبعيا في المقدمة. إلى بايثون 2.2 غريغور لنغل يعلم بايثون في معهد عال في فينا النمسا. و هو يعمل على الترجمة األلمانية للكتاب و قد التقط زوجان من األخطاءالسيئة في الفصل 5. جولي بيترز التقطت خطأ مطبعي في المقدمة فلورين أبرينا أرسلت تحسينا ل maketime و تصحيحا ل printtime. و خطأ مطبعي جميل. دي جي ويبر اقترح توضيحا في الفصل 3. كن وجد حفنة من األخطاءفي الفصول 8 9 و 11. إيفوويفر التقط خطأ مطبعي في الفصل 5 و اقترح توضيحا في الفصل 3 كرتس يانكو اقترح توضيحا في الفصل 2 بن لوغن أرسل لنا عن العديد من األخطاءالمطبعية و مشاكل ترجمة هذا الكتاب جيسن ارمسترنغ رأي الكلمة المفقودة في الفصل 2 لويس كورديه الحظ موضعا في الكتاب حيث النص البرمجي لم يطابق المكتوب. برين كين اقترح عدة توضيحات في الفصل 2 و 3. رب بالك أرسل سلة من التصحيحات من ضمنها التغييرات في بايثون 2.2 إلى HTML. جان-فيلب ريه من Ecole Centrale Paris أرسل عدد من المعلومات الصغيرة من ضمنها بعض التحديثات على بايثون 2.2 و تحسينات معتبرة. جيسن مادر من جامعة جورج واشنطن قام بعدة إقتراحات مفيدة و تصحيحات. يان قندفتة-برون ذكرنا بأن error" a" هي. error ابل ديفد و الكسس دينو ذكرانا بأن جمع matrix هو matrices و ليس matrixes ظل هذا الخطأ في الكتاب لسنوات لكن قارئين بنفس الحروف في أول أسمائهما نبهانا له في نفس اليوم غريب. شارلز تاير شجعنا لكي نتخلص من الفاصلة المنقوطة التي وضعناها في نهاية بعض العبارات و ألن ننظف طريقتنا في استخدام كلمات.parameter و argument روجر سبربرغ أبلغنا عن قطعة منطقية غريبة االطوار في الفصل 3. سام ب ل أبلغنا عن فقرة مشوشة في الفصل 2. اندرو شيونغ تجليتان ل االستخدام قبل التعريف. سي كوري كيبل الحظ كلمة مفقودة في الفرضية الثالثة في تصيد ألساندرة ساعدتنا في توضيب بعض االلتباس في السلحفاة وم شمبين وجد brain-o في مثال القاموس دغلس رايت أبلغ عن مشكلة في القسمة األرضية فيarc جيرد سبند ر وجد بعض المطروحات في نهاية عبارة. األخطاءو األخطاءالمطبعية في الفصل 4
ix فكر بايثون ل ن بيهنغ أرسل عددا من االقتراحات التي تساعد. راي هاختفدت أرسل عن خطأين و عن ليس-خطأ-بمعنى الكلمة. تورستن هوبش أبلغ عن تضارب في سومبي إنغة بتوهوف صححت مثال في الفصل 14. أرن ة بابنهوزنهيد أرسل العديد من التصحيحات المفيدة. مارك إي كاسيدة ماهر في مالحظة الكلمات المكررة. سكوت تايلر مأل "كان هذا مفقودا" ثم أرسل كومة من التصحيحات. جورد ن شبرد أرسل العديد من التصحيحات كلها في رسائل إلكترونية منفصلة. اندرو تيرنر الحظ خطأ في الفصل 8. ادم ه برت أصلح مشكلة في القسمة االرضية فيarc دارل هموند و سارة ز م رمن الحظتا أنني قدمت math.py مبكرا. و زم الحظت خطأ مطبعي. جورج ساس وجد بقة في قسم تصيد البق )عالج االخطاء( بر ي ن بنغهام اقترح التمرين 1.10 ليئة إنغلبرت-فنتون نتبهت إلى أنني استخدم tuple كاسم متغير على خالف نصيحتي أنا. و عثرت على كمية من األخطاءالمطبعية و "االستخدام قبل التعريف" جو فونكة وجد خطأ مطبعي. تشاو-تشاو تشن وجد تناقضا في مثال فيبوناشي جف بين يعرف الفرق بين لوب س بنتس أرسل خطأ مطبعي غريغ لند spam و space و أبيغيل هيته ف اقترحا التمرين 14.4 ماكس هيلبرن أرسل العديد من التصحيحات و االقتراحات. ماكس هو أحد مؤلفي " التجريد المتماسك" العظيم الذي قد تود قراءته بعد انتهائك من هذا الكتاب. شوتيبات بورنهافالي وجد خطأ في رسالة خطأ ستان سلوف أنتول أرسل اقتراحات مفيدة للغاية. إريك بشمن أرسل العديد من التصحيحات في الفصول 4-11. م غو ل أز فيدو وجد بعض األخطاءالمطبعية. جيانهو ليو أرسل قائمة طويلة بالتصحيحات. ن ك كنغ وجد كلمة مفقودة. مارتن زوثر أرسل قائمة طويلة من المقترحات. ادم ز م رمن وجد تناقضا في تجليتي لتجلية و غيرها العديد من االخطاء. راتناكار تيواري اقترح تذييال يشرح تحلل المثلثات. أنوراغ غول اقترح حال اخر ل is_abecedarian و أرسل بعض التصحيحات االضافية. و هو يعلم كيف يهجئ.Jane Austen كيلي كراتزر نتهت إلى خطأ مطبعي. مارك غر ف ثس نبه إلى مثال محير في الفصل 3 رويدن أونجي وجد خطأ في طريقة نيوتن خاصتي. باتريك ولوويتش ساعدني في مشكلة في نسخة.HTML مارك شونفسكي أخبرني عن كلمة مفتاحية جديدة في بايثون. ر س ل كول من ساعدني في حساب المثلثات. ويه هوانغ عثر على عدة أخطاء مطبعية. كارن بربر الحظت أقدم ال األخطاءالمطبعية في الكتاب. نام نغوين وجد خطأ مطبعي و نبه إلى أنني أستخدم نمط التزيين دون االشارة إلى اسمه.
x فكر بايثون ست ف ني مور ن أرسلت العديد من التصحيحات و االقتراحات. بول ستوب صحح خطأ مطبعي في uses_only إريك برونر نبه إلى تشويش في المناقشة حول ترتيب العمليات. أل خاندرو خ ز رلس وضع قاعدة جديدة لنوعية و عدد االقتراحات التي يرسلها. نحن ممتنون للغاية! جري تومس يعلم يساره من يمينه. جيوفاني إسك بار سوسة أرسل قائمة طويلة من التصحيحات و االقتراحات. ألكس إتي ن أصلح إحدى ال.URL كوانغ هي وجد خطأ مطبعي. دانيل نلسن صحح خطأ عن ترتيب العمليات. و ل مكجنس نبه إلى إختالف تعريف polyline في مكانين. سوار ب ساهو عثر على فاصلة منقوطة مفقودة. فرانك هيكر نبه إلى مثال لم يحدد جيدا و إلى بعض الروابط المقطوعة. أنيمش B ساعدني في تنظيف مثال مشوش. مارتن كاسبرسن وجد خطأين ختاميين. غريعور ألم أرسل عدة تصحيحات و اقتراحات. دمتريوس تسيريغس اقترح علي توضيح تمرين. كارلوس تافور أرسل صفحة من التصحيحات و االقتراحات. مارتن نوردسلتن وجد بقة في حل أحد التمارين. الرس أو دي كرستي نسن وجد مرجعا مقطوعا. فكتور سيمون وجد خطأ مطبعي. سف ن هوكستر نبه إلى أن متغيرا يسمة input له ظل اقتران جاهز. فيت لي وجد خطأ مطبعي. ست ف ن غريغوري نبه إلى مشكل مع cmp في بايثون 3. ماثيو شولتز أبلغني عن رابطة مقطوعة. لوكش كومار مكاني أبلغني عن بعض الروابط المقطوعة و عن بعض التغييرات في رسائل الخطأ. إشوار بهات صحح لي عبارتي عن نظرية ف رمات االخيرة. براين مكغي اقترح توضيحا. أندريا زانيلال ترجم هذا الكتاب إلى اإليطالية. و أرسل إلي عدد من التصحيحات في طريقه.
xi فكر بايثون انلتوايت Preface V املقدمة 1. طريق الربانمج The way of the program 1.1. لغة الربجمة ابيثون The Python programming language 1.2. ما هو الربانمج program? What is a.1.3 ما املقصود بعالج الاخطاء debugging?.what is.1.4 اللغة الرمسية و اللغة الطبيعية Formal and natural languages The first program.1.5 الربانمج الاول.1.6 عالج الاخطاء Debugging 1.7. معاين Glossary 1.8. متارين Exercises 2. املتغريات التعبريات و العبارات Variables, expressions and statements 2.1. القمي و الامناط Values and types 2.2. املتغريات Variables Variable names and keywords.2.3 تسمية املتغريات و اللكامت املفاتيح 2.4. املعامالت ومؤثراهتا Operators and operands Expressions and statements.2.5 التعبريات والعبارات.2.6 المنط التفاعيل و منط كتابة النص Interactive mode and script mode 2.7. تراتب معليات املؤثرات Order of operations String operations.2.8 معليات انلارف 2.9. احلوايش Comments.2.10 عالج الاخطاء Debugging
xii فكر بايثون 2.11. معاين Glossary 2.12. متارين Exercises 3. الاقرتاانت Functions 3.1. نداء الاقرتاانت Function calls.3.2 اقرتاانت تبديل منط املتغري Type conversion functions 3.3. الاقرتاانت احلسابية Math functions 3.4. الرتكيب Composition 3.5. اضافة اقرتاانت جديدة Adding new functions.3.6 التعاريف و الاس تخدامات Definitions and uses 3.7. تسلسل تىفيذ الربامج Flow of execution 3.8. الربمرت و القرينة Parameters and arguments Variables and parameters are local.3.9 املتغريات و الربم رتات حملية.3.10 الرمس املس تف Stack diagrams 3.11. الاقرتاانت املمثرة والاقرتاانت العقمية Fruitful functions and void functions.3.12 ملاذا حنتاج اىل الاقرتاانت functions? Why Importing with from.3.13 الاس ترياد ابس تخدام from.3.14 عالج الخطاء Debugging 3.15. معاين Glossary 3.16. متارين Exercises.4 تأمل حاةل: تصممي واهجة مس تخدم Case study: interface design.4.1 عامل السلحفاة TurtleWorld.4.2 تكرار بس يط Simple repetition 4.3. متارين Exercises 4.4. الكبسةل Encapsulation 4.5. التعممي Generalization Interface design.4.6 تصممي واهجات املس تخدم.4.7 التفتيت و البناء Refactoring
xiii فكر بايثون 4.8. خطة تطوير A development plan.4.9 نص التوثيق docstring.4.10 عالج الخطاء Debugging 4.11. معاين Glossary 4.12. متارين Exercises 5. الاجرتار و املرشوطات Conditionals and recursion Modulus operator.5.1 معلية ابيق القسمة مودولوس 5.2. تعبريات بوليانية Boolean expressions 5.3. املؤثرات املنطقية Logical operators 5.4. التنفيذ املرشوط Conditional execution 5.5. التنفيذ البديل Alternative execution 5.6. املرشوطات املسلسةل Chained conditionals.5.7 املرشوطات العش ية Nested conditionals 5.8. الاجرتار Recursion 5.9. رمس مس تف لالقرتاانت املرتة Stack diagrams for recursive functions Infinite recursion.5.10 الاجرتار الالمنهتيي.5.11 مدخالت من لوحة املفاتيح Keyboard input.5.12 عالج الخطاء Debugging 5.13. معاين Glossary 5.14. متارين Exercises 6. الاقرتاانت املمثرة Fruitful functions Return values.6.1 القمي املرجعة من الاقرتان.6.2 تطوير الربامج عصاميا Incremental development 6.3. الرتكيب Composition 6.4. اقرتاانت بوليانية Boolean functions.6.5 املزيد من الاجرتار More recursion 6.6. وثبة ثقة Leap of faith
xiv فكر بايثون One more example.6.7 مثال أخر.6.8 حفص منط املتغري Checking types.6.9 عالج الخطاء Debugging 6.10. معاين Glossary 6.11. متارين Exercises 7. التكرار Iteration 7.1. تعيينات متعددة Multiple assignment 7.2. حتديثاملتغريات Updating variables The while statement break عبارة "طاملا" while 7.3..7.4 عبارة الكبح 7.5. اجلذور الرتبيعية Square roots 7.6. اخلوارزميات Algorithms.7.7 عالج الخطاء Debugging 7.8. اجامل Glossary 7.9. متارين Exercises 8. انلارف Strings A string is a sequence.8.1 اللكمة عبارة عن تسلسل.8.2 طول اللكمة len Traversal with a for loop String slices Strings are immutable.8.3 املرور مع حلقة for.8.4 رشاحئ انلارف.8.5 انلارف ل تتبدل 8.6. البحث Searching 8.7. التدوير و العد Looping and counting String methods The in operator String comparison.8.8 طرق انلارف 8.9. املؤثر in.8.10 مقارنة انلارف.8.11 عالج الخطاء Debugging
xv فكر بايثون 8.12. معاين Glossary 8.13. متارين Exercises Case study: word play.9 دراسة حاةل: اللعب ابللكامت 9.1. قراءة قوامئ اللكامت Reading word lists 9.2. متارين Exercises 9.3. البحث Search.9.4 التدوير ابس تخدام املؤرشات Looping with indices.9.5 عالج الخطاء Debugging 9.6. املعاين Glossary 9.7. متارين Exercises 10. القوامئ Lists 10.1. القامئة عبارة عن تسلسل A list is a sequence 10.2. القوامئ تتبدل Lists are mutable 10.3. املرور يف القوامئ Traversing a list 10.4. معليات القوامئ List operations List slices.10.5 رشاحئ القوامئ 10.6. طرق القوامئ List methods Map, filter and reduce.10.7 توصيل تنقية و اخزتال 10.8. حذف العنارص Deleting elements Lists and strings Objects and values.10.9 القوامئ و انلارف.10.10 الاكئنات و القمي.10.11 تعدد املرجعيات Aliasing List arguments.10.12 القوامئ كقرائن.10.13 عالج الخطاء Debugging 10.14. املعاين Glossary 10.15. متارين Exercises 11. القواميس Dictionaries
xvi فكر بايثون 11.1. القواميس كجموعة من العدادات Dictionary as a set of counters 11.2. التدوير و القواميس Looping and dictionaries 11.3. البحث العكيس Reverse lookup 11.4. القواميس و القوامئ Dictionaries and lists Memos.11.5 املذ كرات 11.6. املتغريات العمومية Global variables.11.7 الاعداد الصحيحة الطويةل Long integers.11.8 عالج الخطاء Debugging 11.9. معاين Glossary 11.10. متارين Exercises 12. التوبالت Tuples Tuples are immutable.12.1 التوبالت ثبيتة ل تتبدل Tuple assignment Tuples as return values.12.2 التعيني للتوبل.12.3 التوبالت كقمية مرجعة 12.4. قرائن طول املتغري Variable-length argument tuples Lists and tuples Dictionaries and tuples Comparing tuples Sequences of sequences.12.5 القوامئ و التوبالت.12.6 القواميس و التوبالت.12.7 مقارنة التوبالت.12.8 تسلسالت من التسلسالت.12.9 عالج الخطاء Debugging 12.10. املعاين Glossary 12.11. متارين Exercises Case study: data structure selection Word frequency analysis.13 دراسة حاةل: اختيار هيالك البياانت.13.1 حتليل تكرار اللكامت 13.2. الارقام العشوائية Random numbers.13.3 مدرج تكراري لللكامت Word histogram Most common words.13.4 اكرث اللكامت ورودا
xvii فكر بايثون 13.5. برمرتات اختيارية Optional parameters.13.6 الطرح يف القواميس Dictionary subtraction 13.7. لكامت عشوائية Random words 13.8. حتليل ماركوف Markov analysis 13.9. هيلكة البياانت Data structures.13.10 عالج الخطاء Debugging 13.11. املعاين Glossary 13.12. متارين Exercises 14. امللفات Files 14.1. الثبات Persistence 14.2. القراءة و الكتابة Reading and writing Format operator Filenames and paths.14.3 مؤثرات التنسيق.14.4 اسامء امللفات و مساراهتا.14.5 التقاط الاس تثناءات Catching exceptions.14.6 قواعد البياانت Databases Pickling.14.7 التخليل 14.8. الاانبيب Pipes Writing modules.14.9 كتابة املديولت.14.10 عالج الخطاء Debugging 14.11. معاين Glossary 14.12. متارين Exercises 15. الفئات و الاكئنات Classes and objects User-defined types Attributes.15.1 أمناط عر فها املس تخدم.15.2 اخلصال Rectangles املس تطيالت.15.3 Instances as return values التجليات كقمية م رجعة.15.4.15.5 الاكئنات ليست ثبيتة تتبدل Objects are mutable
xviii فكر بايثون 15.6. النسخ Copying.15.7 عالج الخطاء Debugging Glossary معاين 15.8. Exercises 149 متارين 15.9. 16. الفئات و الاقرتاانت Classes and functions 16.1. الوقت Time 16.2. الاقرتاانت البحتة Pure functions Modifiers.16.3 لت املعد Prototyping versus planning معل الامنذج املصغرة مقابل التخطيط.16.4 Debugging عالج الخطاء.16.5 Glossary معاين 16.6. Exercises متارين 16.7. 17. الفئات و الطرائق Classes and methods Object-oriented features Printing objects.17.1 خصائص الربجمة اكئنية املنحى.17.2 طباعة الاكئنات 17.3. مثال اخر Another example 17.4. مثال معقد A more complicated example The init method The str method 17.5. طريقة init طريقة str 17.6. 17.7. ارهاق املؤثرات Operator overloading Type-based dispatch Polymorphism.17.8 الايفاد بناءا عىل المنط.17.9 تعدد الشاكل.17.10 عالج الخطاء Debugging Interface and implementation.17.11 واهجة املس تخدم و التطبيق 17.12. معاين Glossary 17.13. متارين Exercises 18. التوريث Inheritance
xix فكر بايثون Card objects.18.1 اكئنات أوراق الشدة 18.2. خصال الفئة Class attributes.18.3 مقارنة اوراق الشدة Comparing cards 18.4. الشدة Decks 18.5. طباعة الشدة Printing the deck.18.6 اضف احذف اخلط و رتب.18.7 التوريث Add, remove, shuffle and sort Inheritance 18.8. رمس الفئة Class diagrams.18.9 عالج الخطاء Debugging 18.10. كبسةل البياانت Data encapsulation 18.11. معاين Glossary 18.12. متارين Exercises.19 دراسة حاةل: يت كنرت Case study: Tkinter.19.1 و م ر واهجة املس تخدم الرسومية GUI.19.2 الازرار و اعادة النداء Buttons and callbacks.19.3 وشائط مقاشة الرمس Canvas widgets 19.4. تسلسالت الاحداثيات Coordinate sequences.19.5 مزيد من الوشائط.19.6 تغليف الوشائط.19.7 قوامئ الاختيار و املس تدعوات More widgets Packing widgets Menus and Callables 19.8. الربط Binding.19.9 عالج الخطاء Debugging 19.10. معاين Glossary 19.11. متارين Exercises أ- عالج الخطاء Debugging الخطاءالنحوية اخطاء عند التشغيل Syntax errors Runtime errors أ- 1 أ- 2
xx فكر بايثون Semantic errors أ- 3 اخطاء دللية ب- حتليل اخلوارزميات Analysis of Algorithms Order of growth تراتب المنو ب- 2 حتليل معليات ابيثون الاساسية Analysis of basic Python operations ب- 3 حتليل خوارزمية البحث Analysis of search algorithms Hashtables Lumpy ج- لميب جداول التقطيع ج- 1 رمس احلاةل State diagram Stack diagram Object diagrams Function and class objects الرمس املستف رمس الاكئن اكئنات الاقرتان و اكئنات الفئة ج- 5 رسوم الفئات Class Diagrams ب- 1 ب- 4 ج- 2 ج- 3 ج- 4
فكر بايثون xxi
الفصل الاول طريق الربانمج هدف هذا الكتاب تعلميك كيف تفكر كعامل حاسوب تفكري جيمع بني بعض من افضل خصائص الرايضيات و الهندسة و العلوم الطبيعية. مفثل علامء الرايضيات يس تخدم عامل احلاسوب لغة رمسية ليصال الافاكر )خصوصا احلسابية(. و كام املهندسني يصممون الش ياء و يقومون بتجميع املكوانت لتصبح نظام مث يقي مون افضل اخليارات من بني العديد من البدائل. و اكلعلامء يراقبون سلوك النظمة املعقدة و يضعون الفرضيات و التنبؤات. املهارة المه لعامل احلاسوب يه حل املشالكت حل املشالكت يعين تفسريها بصيغة رمسية مث التفكري اخلالق ابحللول مث التعبري عن احلل تعبريا واحضا و دقيقا. احلق أن معلية تعمل الربجمة يه فرصة ت ق صتن للمترن عىل املهارات العديدة حلل املشالكت و لهذا مسي هذا الفصل " طريق الربانمج". مفن انحية ستتعمل الربجمة و يه همارة مفيدة ذلاهتا و من انحية اخرى ستسخدم الربجمة كوسيةل لهدف ابعد ستتضح كل معامله لكام تقدمنا معا. 1.1 لغة الربجمة ابيثون لغة الربجمة اليت ستتعلمها هنا يه ابيثون. و ابيثون مثال للغات الربجمة عالية املس توى قد تكون قد مسعت عن لغات برجمة عالية املس توى مثل يس يس بلس بلس بريل و جافا. يوجد ايضا ما يسمى بلغة منخفضة املس توى تدعى احياان لغة الاةل او لغة التجميع. احلواسيب تشغل الربامج املكتوبة ابللغات منخفضة املس توى فقط ذلكل فان الربامج املكتوبة بلغة عالية املس توى لن تعمل قبل معاجلهتا. هذه املعاجلة تستنفذ بعض الوقت لكنه ليس سوى سيئة صغرية للغات عالية املس توى. حسنات اللغات عالية املس توى ل حتىص أولها: سهوةل كتابة الربامج. فكتابة الربامج ابللغات عالية املس توى تتطلب وقتا اقل و الربامج املكتوبة تكون اقرص و اسهل للقراءة و احامتل خلوها من الخطاء اكرب. اثنهيا: قابليهتا للنقل اي ان الربانمج املكتوب بلغة عالية املس توى س يعمل عىل انواع خمتلفة من احلواسيب بتعديل بس يط او حىت بدون اي تعديل. اللغات منخفضة املس توى تعمل عىل نوع واحد من احلواسيب و جيب كتابهتا مرة اخرى لتعمل عىل نوع اخر.
فكر بايثون 2 الشلك 1.1: املف رس يعاجل الربانمج قليال لك مرة فيقرأ سطور الربانمج و ينفذ العمليات الشلك 1.2: املرتمج يرتمج النص الاصيل اىل اىل تشفري شييئ مث تنفذه مكوانت احلاسوب املادية لجل هذه املزااي تكتب مجيع الربامج تقريبا ابللغات عالية املس توى بيامن تس تخدم اللغات منخفضة املس توى يف تطبيقات متخصصة. هناكل نوعان من الربامج اليت تعاجل اللغات عالية املس توى لتصبح لغة أةل: املف رسات و املرتجامت. املف رس يقرأ سطور برانمج مكتوب بلغة عالية و ينفذها اي انه ينفذ ما يقول الربانمج معاجلا اوامره واحدا تلو الاخر. فيقرا السطور و يقوم ابلعمليات احلاسوبية. الشلك 1.1 يبني هيلك املف رس. اما املرتمج فيقرا الربانمج و يرتمجه اكمال قبل تشغيهل. يف هذا الس ياق يسمى الربانمج املكتوب بلغة عالية املس توى ابلنص الصيل و الربانمج املرتمج ابملشفر الشييئ أو الربانمج القابل للتىفيذ. مبجرد ترمجة الربانمج سميكن تشغيهل مرارا دون احلاجة اىل الرتمجة. الشلك 1.2 يبني هيلك املرتمج. يعترب ابيثون النص. مف رسا الربامج املكتوبة تنفذ عن طريق مف رس. هناكل طريقتان لس تخدام املف رس: يف الوضع التفاعيل س تكتب برانمج ابيثون و املف رس سينفذه كل و يظهر النتيجة: اشارات >>> )انلث( تعين ان املف رس جاهز فان طبعت 1+1 فسريد املف رس ب 2. الوضع التفاعيل و وضع كتابة >>> 1 + 1 2 يف املقابل ميكنك ختزين النص الصيل يف ملف مث اس تخدام املف رس لتنفيذ حمتواه. ما اجت مع عليه هو ان ملفات ابيثون تنهتيي ب (.).py و ليك ي نفذ النص عليك ابالغ ابيثون ابمس امللف. فلو اكن دليك نصا خمزان حتت امس dinsdale.py و كنت تعمل عىل UNIX فس تطبع. python dinsdale.py ختتلف هذه التفاصيل من بيئة تشغيل اىل اخرى ابماكنك احلصول عىل معلومات هبذا اخلصوص من موقع. http://python.org العمل يف الوضع التفاعيل مفيد لفحص القطع الربجمية الصغرية لنك تس تطيع تىفيذها مبارشة. لكن للك ما هو اكرب من بضعة سطور س يكون عليك ختزين النص حبيث ميكنك تعديهل و تنفيذه مس تقبال.
1.2 ما هو الربانمج فكر بايثون 3 الربانمج هو مجموعة تعلاميت مرتبة حتدد طريقة تنفيذ معلية حوسبة. احلوسبة قد تكون شيئا حسابيا كحل منظومة من املعادلت او اجياد جذور كثريات احلدود ال اهنا قد تكون حوسبة رمزية اكلبحث و استبدال النصوص يف وثيقة او )و اي للعجب( ترمجة برانمج. ختتلف تفاصيل التعلاميت ابختالف اللغات ال ان بضعة تعلاميت اساسية س تتبدى تقريبا يف لك لغة: امل دخالت: احلصول عىل املعلومات من لوحة املفاتيح او امللفات او اي اداة اخرى. امل خرجات: اظهار املعلومات عىل الشاشة او ارسالها اىل ملف او اي اداة اخرى. احلساب: القيام ابلعمليات احلسابية الاساسية اكمجلع و الرضب. التنفيذ املرشوط: تنفيذ معلية ما ان حتققت الرشوط. التكرار: القيام بعمل ما مرارا و عادة ما يكون مع بعض التغيري. صد قت ام ل هذا تقريبا لك ما ينطوي عليه الربانمج. لك برانمج اس تخدمته بغض النظر عن مدى تعقيده بين عىل تعلاميت كهذه ذلا ميكنك التفكري يف الربجمة عىل اهنا تقسمي ملهمة خضمة معقدة اىل همامت اصغر فاصغر حىت تصبح بس يطة اىل احلد اذلي ميك ننا من تنفيذها هبذه التعلاميت. قد ل يزال هذا غامضا الا اننا س نعود اىل هذه النقطة عند احلديث عن اخلوارزميات. 1.3 تصحيح الاخطاء ما املقصود ب Debugging الربجمة عرضة للخطأ و لمر غريب تدعى اخطاء الربجمة بق )كتكل احلرشة( و معلية صيد )أو تدعى مقل و تصيدها تفلية(. الخطاء تدعى Debugging هناكل ثالثة انواع من الخطاء اليت قد حتدث خالل الربجمة: اخطاء حنوية اخطاء عند التشغيل و الخطاء ادلللية. من املفيد التفريق بيهنا لترسيع معلية صيد الخطاء. 1.3.1 الخطاءالنحوية Syntax Errors ابماكن ابيثون تنفيذ الربامج فقط ان اكنت خالية من الخطاء النحوية و ا ل فس يطبع مف رس ابيثون رساةل وجود خطأ يتعلق ابلخطاء النحوية. الخطاء النحوية تشري اىل بناء الربانمج و القوانني اليت حتمك حنوه فالقواس مثال ل تقبل ا ل اذا اكنت ازواجا ف )2+1( قانونية اما )8 فهيي خطأ حنوي. يف العربية يتسامح القراء مع معظم الخطاء النحوية هل لحظت أنك تقرأ رسائل عىل مواقع التواصل الجامتعي مليئة ابلخطاء النحوية لكنك تتغاىض و ل ترسل.Error message يف املقابل فان ابيثون ليس متساحما ابملر ة فبوجود خطأ واحد يف الربانمج س يطبع رساةل وجود خطأ و يتوقف عن التنفيذ و لن يكون ابماكنك تشغيل الربانمج. خالل الاسابيع الاوىل يف حياتك الربجمية س يأخذ تصيد و تصحيح الخطاء الكثري من وقتك لكن مع اكتسابك للخربة س تقوم بأخطاء اقل و س تعاجلها بشلك ارسع.
فكر بايثون 4 1.3.2 الخطاء اليت تظهر عند التشغيل Runtime Errors النوع الثاين من الخطاء مسي كذكل لن هذه الخطاء ل تظهر خالل التصممي بل بعد تشغيل الربانمج. هذه تسمى ايضا اس تثناءات لهنا تؤرش حبدوث امر اس تثنايئ )يسء(. الخطاء 1.3.3 الخطاء ادلللية )التأويل( Semantic Errors ان اكن ابلربانمج خطأ دليل فان الربانمج س يعمل بنجاح - من انحية عدم اصدار رسائل بوقوع خطأ ما- ابلعمل املطلوب بل س يقوم بعمل أخر. أو لدلقة: س يقوم مبا طلب منه القيام به. ال أنه لن يقوم س تكون املشلكة ان الربانمج اذلي مقت بكتابته ليس ذكل اذلي اردت كتابته. مفعىن الربانمج )دلليته( خطأ. التعرف عىل الخطاءادلللية اكلتعرف عىل اخلدع لنه يتطلب منك العمل بشلك عكيس س يكون عليك تأمل خمرجات الربانمج مث حماوةل معرفة ما يقوم به. 1.3.4 تصيد الخطاء جتريبيا من أمثن املهارات اليت س تحصل علهيا يه تصيد الخطاء و تصحيحها و مع أهنا حمبطة ال ان هذه املهارة يه اجلزء الاكرث حتداي و ااثرة و اثراءا للثقافة اذلاتية. مفن انحية يشبه تصيد الخطاء معل التحري هناكل أدةل بني يديك و عليك ختمني الحداث و العمليات اليت ادت لوقوع اخلطأ اذلي تراه. تصيد الخطاء اكلعلوم التجريبية فمبجرد ورود فكرة يف رأسك عام أوصل اىل هذا اخلطأ ستبدأ بتعديل الربانمج و جتربته مرة اخرى فان اكنت افرتاضاتك حصيحة ستمتكن من التنبؤ بنتيجة التعديل الاخري مث تقوم بتعديل أخر يقربك من برانجمك املقصود. و ان اكنت افرتاضاتك خاطئة س يكون عليك التيان بفرضية اخرى. فكام بني شريلوك هوملز"ان أزلت من املس تحيالت مفا يتبقى س يكون احلقيقة همام بدت ل تصدق" )أ كوانن دويل عالمة الاربعة(. البعض يرى الربجمة و تصي د الخطاء شيئا واحدا لكون الربجمة تصيدا متواصال للخطاء اىل تنهتيى اىل برانمج يقوم مبا تريده ان يقوم به. الفكرة يه ان عليك البدء بربانمج يقوم بيشء ما مث تبدأ ابضافة التعديالت الصغرية و تصيد اخطاهئا و تصحيحها بيامن تسري يف طريقك حنو الربانمج املكمتل فيكون امامك برانجما خاليا من الخطاء طوال معلية البناء. عىل سبيل املثال Linux نظام تشغيل حيتوي عىل الالف من سطور الربجمة الا انه بدأ بربانمج صغري بناه لينوس تورفادلز ليك يسكشف رشحية انتل. 80386 و حسب لري جرينفيدل "احدى مشاريع لينوس الاوىل اكنت برانجما ابماكنه التبديل بني طباعة AAAA و.BBBB تطور هذا الربانمج لحقا اىل "Linux )من Users' The Linux.)Guide Beta Version 1 يف الفصول الاخرية تنتظرك اقرتاحات اكرث حول تصيد الخطاء و كذكل حول املامرسات الصحيحة يف الربجمة.
1.4 اللغات الرمسية و اللغات الطبيعية: فكر بايثون 5 اللغات الطبيعية يه ما يتحدث به الناس اكلعربية و الاجنلزيية مل يصمم الناس هذه اللغات )رمغ حماولهتم وضع القواعد لها( هذه اللغات تطورت طبيعيا. اللغات الرمسية: لغات مصمها الناس لت طب ق يف أجواء معينة. الشارات احلسابية اليت يس تخدهما الرايي يه لغة رمسية ت س تخدم يف حتديد العالقة بني الرقام و الرموز. الكمييائيون يس تخدمون لغة رمسية للتعبري عن تركيب اجلزيء و المه: لغات الربجمة يه لغات رمسية مصمت للتعبري عن معليات احلوسبة للنحو يف اللغات الرمسية قواعد صارمة ف = 6 3 + 3 صيغة حصيحة يف حني 3$6 = +3 صياغة خاطئة كذكل H 2 O صيغة حصيحة ملعادةل كمييائية لكن 2Zz ليست كذكل. قواعد النحو تأيت بنكهتني تتعلقان برموز اللغة token و بناهئا. رموز اللغة يه عنارص اللغة الاساس ية اكللكامت و الرقام و العنارص الكمييائية. فاملشلكة يف 3$6 = +3 يه أن $ ليست رمزا قانونيا يف الرايضيات )عىل القل عىل حد علمي( كذكل.Zz ليست قانونية لعدم وجود عنرص يرمز هل 2Zz النكهة الثانية من حنو اللغة تتعلق ببناهئا أي كيف ترتب رموز اللغة. فالعبارة = 3 + 3 غري حصيحة رمغ كون + و = رموزا رايضية قانونية ال اننا ل نس تطيع وضعها اىل جانب بعضها هذا ينطبق عىل املعادلت الكمييائية ايضا فالرقام املنخفضة تأيت بعد رموز العنارص ل قبلها. مترين : 1.1 اكتب مجةل عربية حصيحة القواعد لكن بلكامت غري حصيحة مث اكتب اخرى بلكامت حصيحة و بنحو غري قانوين. ان كنت تقرأ مجةل عربية أو عبارة ذات صياغة رمسية س يكون عليك تبني حنو امجلةل )علام بأنك تفعل هذا مع اللغات الطبيعية دون ان تنتبه( هذا ما يسمى يف العربية "العراب و الرصف" يف الاجنلزيية Parsing سنتحدث من الان عن الاجنلزيية فقط!! مفثال عند سامعك dropped" "The penny س تفهم بأن penny" "The هو املوضوع )subject( و أن "dropped" هو املمتمة للجمةل.)predicate( مبجرد اعرابك للجمةل س يكون ابماكنك فهمها أو معرفة "دللهتا" its semantic هذا الفهم مرشوط بكونك تعمل ما هو ال Penny و معىن السقوط. تتشابه اللغات الرمسية و الطبيعية يف نواح عدة الا اهنا ختتلف يف بعض الامور: الغموض: اللغات الطبيعية يلفها الغموض يتحايل الناس عىل هذا ابلدةل اليت تفهم من الس ياق. اللغات الرمسية مصمت لتكون واحضة متاما مما يعين أن للك عبارة مع ىىن واحد فقط بغض النظر عن الس ياق. الوفرة: متتكل اللغات الطبيعية الكثري من اللكامت ليك تعوض مغوضها و لتجنب الفهم اخلاطئ و نتيجة لهذا غالبا ما تكون كثرية الاطناب. اللغات الرمسية أفقر و أوجز. املعىن احلريف: اللغات الطبيعية مليئة ابلتكنية فعندما نقول "القشة اليت قصمت ظهر البعري" قد ل يكون هناك بعري و ل قشة و ل يشء قد كرس اساسا. اللغات الرمسية تعين ابلضبط ما تقوهل. الناس اذلين تربوا عىل اس تعامل اللغات الطبيعية )لك الناس( جيدون صعوبة يف التحول اىل اللغات الرمسية أحياان يكون الفرق بيهنا كذكل اذلي بني الشعر و اخلطابة بل أكرب: الشعر: ت س تعمل اللفاظ لصوهتا و ملعناها القصيدة كلك ت عمل تأثريا و ردة فعل عاطفية و غالبا ما يكون الغموض يف املعاين الشعرية مقصودا. اخلطابة: املعىن الرصحي للعبارات هو املهم هنا طريقة حنو امجلل تسامه يف املعىن الاجاميل حتليل اخلطب اسهل
فكر بايثون 6 من حتليل القصائد ا ل اهنا تظل حتتوي عىل الغموض. الربانمج: معىن برانمج احلاسوب واحض و حريف ميكن فهمه لكيا عن طريق حتليل رموزه و بنائه. اليك الان بعض الاقرتاحات لقراءة الربامج )و كذكل اللغات الرمسية الاخرى(. أول تذكر ان اللغات الرمسية مكثفة عىل عكس الطبيعية ذلا فقراءهتا س تأخذ وقتا اطول مث تذكر بأن بنيان الربانمج يف غاية الامهية ذلكل فبدل من قراءة الربانمج من الاعىل اىل الاسفل و من اليسار اىل الميني تعمل حتليل هيلك الربانمج يف رأسك و تعريف رموز الربانمج و تفبسري بناءه. اخريا انتبه للتفاصيل فالخطاء المالئية اليت غالبا ما نتساهل معها يف اللغات الطبيعية لها تبعات أعظم يف اللغات الرمسية. الربانمج الاول 1.5 تقليداي اول برانمج تكتبه بلغة برجمة جديدة يسمى World!" "Hello, عىل الشاشة. يف ابيثون يكتب هذا الربانمج اكلتايل: هذا مثال عىل عبارة print رمغ ان الشاشة. القمية يف هذه احلاةل يه اللكامت: "Hello, World!" لن لك ما س يفعهل هو اظهار هذه امجلةل print 'Hello, World!' print تعين "اطبع" فهذا الربانمج ل يطبع اي يشء عىل الورق فقط يظهر قمية عىل عالمات الاقتباس )'( حتدد بداية و هناية النص املطلوب عرضه و لن تظهر عند عرض النتيجة. يف ابيثون 3 ختتلف الصيغة قليال: Hello, World! Print('Hello, World!') الاقواس هنا تعين أن print يه اقرتان سنناقش الاقرتاانت لحقا يف الفصل الثالث. سأس تخدم print كعبارة حىت هناية الكتاب فان اكنت نسختك النسختني قليةل فال تقلق بسبهبا. بايثون 3 فالفروق بني عدا ذكل ما فعليك ترمجهتا.
تصيد الاخطاء 1.6 فكر بايثون 7 الافضل قراءة هذا الكتاب مقابل حاسوبك ليك تمتكن من تطبيق الامثةل مبارشة ابماكنك جتربة معظم الامثةل يف الوضع التفاعيل ال انه اذا كتبت الربانمج يف الوضع النيص ستمتكن من جتريب التعديالت عليه. عندما تتدرب عىل أوامر جديدة عليك ان حتاول تعمد اخلطأ مفثال ما اذلي س يحدث يف برانمج نسيت و ضع احدى عالميت الاقتباس أو الكهام ما اذلي س يحدث لو أخطأت هتجئة لكمة print "Hello, World!" ان هذا النوع من التجريب يساعدك عىل تذكر ما تقرأ هنا و سيساعدك عند تصيد الاخطاء فليك تتذكر دامئا ما اذلي تقصده الرساةل اليت تفيد بوجود خطأ ما من الافضل القيام بذكل اخلطأ الان و عن قصد بدل من انتظار حدوثه عرضيا. أحياان تثري الربجمة بعض املشاعر خصوصا تصيد الاخطاء فقد حتس ابلحباط عندما يواهجك خطأ برجمي عيص عىل احلل و قد تشعر حىت ابلغضب. هناكل دلئل عىل ان البرش قد يتعاملون مع احلواسيب كام لو اكنت برشا مثلهم فان اكنت تعمل جيدا فهيي جزء من الفريق وا ل فهيي فظة و منم فرد ات فعلهم س تكون كتكل حنو الفظني من الناس ( ريفز و نس معادةل امليداي: كيف يعامل الناس احلواسيب التلفزيوانت و امليداي اجلديدة اكلناس و المكنة(. قد يساعدك ان تتحرض لردات الفعل هذه يف التعامل معها. احدى الطرق يه اعتبار احلاسوب احد موظفيك هل نقاط قوة حمددة اكلرسعة و ادلقة و هل كذكل نقاط ضعف معينة كعدم الاحساس مع الاخرين و عدم بعد النظر. هممتك يه ان تكون املدير اجليد اس تفد اذن من همارات و دقة هذا املوظف مث تقب ل فظاظته و عدم رؤيته للصورة الاكمةل مث جد الس بل لس تخدام عواطفك من غضب و جخل يف حل املشالك دون ان تسمح لردات فعكل من أن تنتقص من كفاءتك يف العمل. الاحباط من سامت التدرب عىل همارة صيد الاخطاء الا ان قمية امتالك هذه املهارة تتخطى تصحيح اخطاء الربامج اليت تكتهبا اىل كثري من فعالياتك اليومية. يف هناية لك فصل من فصول هذا الكتاب هناك قسم عن تصيد الاخطاء كهذا و به س تجد كيف افكر عندما اتصيد الاخطاء امتىن ان يكون ذا فائدة كل. 1.7 املشالك حل معاين: :problem solving معلية متاكمةل تشمل صياغة املشلكة اجياد حل لها مث التعبري عن هذا احلل. لغات عالية املس توى :high-level language لغات برجمة كبايثون مصممة ليك تكون سهةل القراءة و الكتابة. لغات منخفضة املستوى :low-level languag لغات برجمة مصممة ليك ينفذها احلاسوب بسهوةل تسمى أيضا "لغة الةل" أو "لغة التجميع". التنقلية :portability قابلية الربانمج للعمل عىل أكرث من نوع من احلواسيب. تفسري :interpret تنفيذ سطور الربانمج املكتوب بلغة عالية املس توى واحدا بعد الاخر. مجع الربانمج :compile ترمجة الربانمج املكتوب بلغة عالية املس توى اىل لغة منخفضة املس توى دفعة واحدة اس تعدادا لتنفيذه لحقا. النص الاصيل :source code الربانمج املكتوب بعغة عالية املس توى قبل مجعه. نص الاكئن :object code ما ينتج عن مجع الربانمج.
فكر بايثون 8 قابل للتنفيذ :executable امس اخر لنص الاكئن عندما يكون جاهز للتنفيذ. حمث :prompt اشارات>>> يظهرها املف رس مظهرا اس تعداده لس تقبال املدخالت. خمطوط برجمي :script برانمج خ زن يف ملف ( عادة ما س يرتمج لحقا(. الوضع التفاعيل :interactive mode احد اس تخدامات مف رس ابيثون بأن تطبع الاوامر و التعبريات مبارشة بعد انلث. الوضع الكتايب :script mode احد اس تخدامات مف رس ابيثون بأن يقرأ و ينفذ عبارات نص برجمي. برانمج :program مجموعة من التعلاميت حتدد العملية احلوسبية. خوارزمية :algorithm طريقة عامة حلل نوع من املشالك. بقة :bug خطأ يف الربانمج. تصحيح الاخطاء :debugging معلية تصيد أي من الخطاء الثالثة و تصحيحها. النحو :syntax بناء الربانمج. خطأ حنوي :syntax error خطأ يف الربانمج اما أماليئ او حنوي ل ميكن معه اعرابه )و ابلتايل ل ميكن تفسريه(. اس تثناء :exception خطأ ظهر فقط عندما شغل الربانمج. دلةل :semantics املقصود من الربانمج. خطأ دليل :semantic error خطأ يف الربانمج جيعل انجت الربانمج غري ذكل اذلي قصد منه. اللغات الطبيعية :natural languages تكل اللغات اليت يتحدهثا البرش تطورت طبيعيا. اللغات الرمسية formal languages كلت: اللغات اليت مصمها البرش لتس تخدم يف حالت حمددة. رمز :token أحد مكوانت بناء نص الربانمج الاساس ية مرادف لللكمة يف اللغات الطبيعية. اعراب :parsing حفص نص الربانمج و حتليل بنائه النيص. عبارة اطبع :print statement من تعلاميت مف رس ابيثون تظهر قمية عىل الشاشة.
متارين: 1.8 مترين 1.2 اذهب اىل تتعلق به. تس تطيع البحث هناك يف واثئق ابيثون. http://python.org فكر بايثون 9 حتتوي هذه الصفحة عىل معلومات عن ابيثون و هبا وصالت مثال ان حبثت عن لكمة print فان اول نتيجة س تظهر يه واثئق. print يف هذه املرحةل قد ل تعين كل شيئا ان معرفة ماكهنا س يكون مفيدا. مترين 1.3 شغل مف رس ابيثون و اطبع() help لتشغ ل املساعدة ابماكنك طباعة: ا ل help('print') ان مل يعمل هذا املثال س يكون عليك تنصيب مزيدا من واثئق ابيثون أو حتديد متغري البيئة تفاصيل حل هذه املشلكة تعمتد عىل نظام التشغيل. مترين 1.4 شغل مف رس ابيثون و اس تخدم الربانمج كحاسبة. بناء املعادلت يف ابيثون تقريبا نفس بناء املعادلت العادي مفثال الرموز + و - و / تعين امجلع و الطرح و القسمة الا ان رمز الرضب هو *. ان ركضت 10 مك يف س باق مبدة 43 دقيقة و 30 اثنية مفا هو معدل الوقت ابمليل ما هو معدل رسعتك ابمليل يف الساعة )تلميح: يوجد 1.61 مك يف امليل(.
فكر بايثون 10
فكر بايثون 11 الفصل الثاين املتغريات التعبريات و العبارات القمي و امناطها 2.1 احد الاش ياء الاساس ية اليت يتعامل هبا الربانمج هو 'Hello, World!' القمية اكحلرف أو الرمق القمي اليت مرت بنا حىت الان يه 1 و 2 و تنمتي القمي لعدة أمناط: ف 2 عدد حصيح أما World!' 'Hello, فهو سلسةل من احلروف )حمارف(. ابماكنك )و كذكل ابماكن املف رس( التعرف عىل انلارف لهنا حمصورة بني عالميت اقتباس. ان مل تكن متأكدا من منط القمية اليت بني يديك فسيساعدك املف رس: >>> type('hello, World!') <type 'str'> >>> type(17) <type 'int'> من الواحض ملاذا جيب أن تنمتي انلارف strings اىل منط امسه str و أن تنمتي الاعداد الصحيحة integers اىل المنط.int الاقل وضوحا هو ان الارقام اليت حتتوي عىل كسور عرشية )الاعداد احلقيقية( تنمتي اىل منط يدعى )عامئ( float و ذكل لن هذه الارقام متث ل بصياغة تدعى floating-point )النقطة العرشية العامئة(. ماذا عن قمي ك '17' و ' 32 ' تبدو أرقاما الا أهنا بني عالميت اقتباس اكنلارف.strings اذن فهيي حمارف. >>> type(3.2) <type 'float'> >>> type('17') <type 'str'> >>> type('32') <type 'str'> عند كتابة الاعداد الكبرية يقسمها البعض اىل مجموعات من ثالث خاانت ك 1,000,000 ابس تخدام فاصةل هذا غري قانوين كعدد حصيح يف ابيثون الا انه قانوين: >>> 1,000,000 (1,0,0)
فكر بايثون 12 الشلك 2.1: رمس احلاةل. message n pi 'Amd now for something completely different' 17 3.1415926535897932 مل نتوقع هذا ابملرة!! لقد فرس ابيثون الرمق 1,000,000 عىل أنه تسلسل أعداد حصيحة مقسمة بفاصةل. هذا أول مثال نراه عىل الخطاءادلللية: مل تظهر رسائل وجود الاخطاء لكن الربانمج ل يفعل "ما قصد منه". املتغريات 2.2 من أقوى خصائص لغات الربجمة يه قدرهتا عىل التالعب ابملتغريات املتغري هو امس يعطى لقمية. عبارات التعيني توجد متغريات جديدة و تعطهيا قمي: قام هذا املثال بثالثة تعيينات الاول الثالث ع ني قمية π )تقريبية( >>> message = 'And now for something completely different' >>> n=17 >>> pi=3.1415926535897932 تعيني حمارف ملتغري امسه message و الثاين أعطى عددا حصيحا للمتغري n و ل.pi الطريقة الشائعة عند متثيل املتغريات عىل الورق يه كتابة امس املتغري مث رمس سهم يؤرش لقميته. هذا النوع من الشاكل يسمى رمس احلاةل state diagram لنه يظهر احلاةل اليت يوجد فهيا املتغري )فكر هبا كحاةل املتغري اذلهنية(. الشلك 2.1 يوحض نتيجة املثال السابق. منط املتغري هو منط القمية املعينة هل. >>> type(message) <type 'str'> >>> type(n) <type 'int'> >>> type(pi) <type 'float'> 2.3 تسمية املتغريات و الاسامء انلجوزة خيتار املربجمون ملتغرياهتم اسامء لها معىن يف العادة أي أهنم يوث قون لي يشء سيس تخدم ذكل املتغري منذ حلظة اجياده. ميكن لسامء املتغريات أن تكون طويةل و ان حتوي حروفا و أرقاما لكن جيب ان تبدأ حبرف. من املسموح اس تخدام احلروف الكبرية ا ل انه من الافضل اس هتالل امس املتغري حبرف صغري )سرتى ملاذا مع س ياق احلديث(. ل ميكن اس تخدام الفراغات أيضا. ميكن لرمز اخلط السفيل _ أن يظهر يف امس املتغري يس تخدم هذا الرمز عاد ىة لتقسمي اسامء املتغريات املكونة من أكرث من لكمة لتعويض الفراغات ك my_name أو.air_speed_of_unladen_swallow
ان س تخدمت اسام ليس قانونيا ملتغري س تحصل عىل رساةل وجود خطأ حنوي: اكنت 76trombones غري قانونية لن الامس اس هتل بغري حرف أما قانوين@ لكن ما مشلكة class فكر بايثون 13 >>> 76trombones = 'big parade' SyntaxError: invalid syntax >>> more@=1000000 SyntaxError: invalid syntax >>> class = 'Advanced Theoretical Zymurgy' SyntaxError: invalid syntax more@ مفشلكهتا احتواهئا عىل رمز غري سيتضح لنا بأن class يه لكمة مفتاحية حمجوزة. يس تخدم املف رس لكامت مفتاحية ليك يتعرف عىل بناء الربانمج و هذه اللكامت ل جيوز اس تخداهما لتسمية املتغريات. دلى ابيثون 2 احدى و ثالثني لكمة مفتاحية: and del from not while as elif global or with assert else if pass yield break except import print class exec in raise continue finally is return def for lambda try يف ابيثون 3 مل تعد exec لكمة مفتاحية لكن nonlocal اصبحت لكمة مفتاحية. رمبا من الافضل كل ان تبقي هذه القامئة قريبة منك فان اشتىك املف رس من اس تخدامك امس ما ملتغري س تعمل ملاذا. 2.4 العوامل و مؤثراهتا املؤثرات يه رموز متثل معليات ح وسبة اكمجلع و الرضب اما القمي امل ؤث ر علهيا فهيي العوامل. املؤثرات + - h * و تقوم ابمجلع و الطرح و القسمة و الرضب كام يف املثال التايل: 20+32 hour-1 hour*60+minutes 5**2 (5+9)*(15-7) يف لغات اخرى تسخدم اشارة ^ للتعبري عن الأس لكن يف ابيثون تس تخدم هذه الاشارة يف العمليات املنطقية و تدعى.XOR لن ارشح البتوايز bitwise( تعين املعاجلة عن طريق اصغر جزء من املعلومة( هنا ابماكنك القراءة عهنا هنا http://wikipythonorg/moin/bitwiseoperators يف ابيثون 2 قد ل يقوم مؤثر القسمة مبا تتوقع منه: >>> minute=59 >>> minute/60 0 قمية املتغريminute يه 59 و قسمهتا عىل 60 جيب ان تنتج 0.98333 و ليس صفرا. السبب يف هذا اخللل هو أن ابيثون يقوم بقسمة أرضية )أي أن الناجت هو العدد بعد حذف الكسور 2=5/2( و عندما يكون طريف القسمة اعداد حصيحة فالناجت س يكون أيضا عدد حصيح القسمة الرضية حتذف الكسور من انجت القسمة و تقربه اىل الصحيح الاقل منه: اكن هذا الصفر هنا.
يف ابيثون 3 انجت هذه القسمة / فكر بايثون 14 هو قمية حقيقية )تقبل الكسور( و هناكل رمز جديد هو hh يقوم بقسمة ان اكنت قمية أي من العاملني حقيقية فان ابيثون يقوم بقسمة حقيقية و تكون نتيجهتا حقيقية أيضا: أرضية. >>> minute/60.0 0.98333333333328 2.5 التعبريات و العبارات التعبري هو تركيبة من القمي و املتغريات و املؤثرات. القمية حبد ذاهتا تعترب تعبريا فلك ما ييل يعترب تعبريا جائزا )عىل اعتبار أن قمي ىة ما عينت للمتغري x(: العبارة يه لبنة برجمية يف النص ميكن لبايثون أن ينفذها مرت علينا عباراتن 17 x x+17 print و عبارة التعيني. معليا فالتعبري هو أيضا عبارة لكن قد يكون من الاسهل التفكري هبام كش يئني خمتلفني الفرق المه هو أن للتعبري قمية أما العبارة فال. الربجمة وضع 2.6 وضع التفاعيل و كتابة نص الربانمج من حسنات الربجمة ابس تخدام املف رس يه انه ميك نك من جتريب أجزاء الربانمج الصغرية قبل وضعها يف اهلطوط الربجمي ال أن هناك فروقا بني وضعي اس تخدامه قد تلتبس عليك. مثال ان كنت تس تخدم ابيثون كةل حاس بة فقد تطبع: >>> miles = 26.2 >>> miles * 1.61 42.182 السطر الاول عبارة تعني قمية للمتغري miles لكن ليس لهذا التعيني تأثري ظاهر. السطر التايل هو تعبري ذلا يقوم املف رس بتقيميه و عرض الناجت فنفهم عندها بأن املاراثون هو حوايل 42 مك. ال انك ان طبعت نفس النص الربجمي يف وضع كتابة النص الربجمي و شغلت الربانمج فلن حتصل عىل يشء لن التعبري حبد ذاته ليس هل تأثري مريئ يف وضع كتابة النص الربجمي. يف احلقيقة ابيثون يقمي التعبري ال أنه ل يظهر نتيجته ال ان طلب منه ذكل: قد يكون هذا الترصف مشوشا يف البداية. miles = 2.62 print miles * 1.61 يف العادة و عندما حيتوي النص الربجمي عىل تسلسل من العبارات فان انجت العبارات يظهر واحدا تلو الاخر لكام نفذت عبارة. مثال النص: س يظهر اهلرجات: print 1 x = 2 print x
فكر بايثون 15 1 2 5 x = 5 x + 1 عبارة التعيني x = 2 مل تنتج أي خمرجات. مترين 2.1 اطبع العبارات التالية يف مف رس ابيثون لرت ماذا تفعل: املؤثرات معليات تراتب 2.7 عندما حيتوي تعبري ما عىل أكرث من مؤثر فان تراتب تقيمي العمليات يعمتد عىل قوانني الاولوية للعمليات احلسابية. يت بع ابيثون الجامع املعروف. الاختصار PEMDAS طريقة سهةل لتذكر هذا الاجامع: :Parentheses الاقواس لها الاولية القسوى و ابماكنك اس تخداهما لرغام ابيثون عىل اتباع التسلسل اذلي تريده. فامب أن التعبريات املوجودة بني أقواس تنفذ أول فان =)3-1(*2 4 و كذكل )2-5(**)1+1( ابماكنك أيضا اس تخدام الاقواس لتسهيل قراءة العبارات كام يف )minute*100(h60 تساوي 8. حىت و ان مل تغري النتيجة. 4 و كذكل 3 و ليس 1+1**2 تساوي يف الاولوية فان التالية يه :Exponentiation السس تساوي 3 و ليس 27. 3**1*3 Multiplication و :Division الرضب و القسمة هلام نفس الاولوية اليت يه أعىل من امجلع و الطرح و 3-1*2 تساوي 5 و ليس 4 كذكل 6+4/2 تساوي 8 و ليس 5. اللتان هلام نفس الولوية كذكل فان degrees/2*pi املؤثرات اليت لها نفس الاولوية تنفذ من اليسار اىل الميني )ما عدا الس(. ذلا ففي التعبري تنفذ القسمة أول و نتيجهتا ترضب يف. pi ان أردت القسمة عىل 2π فعليك اس تخدام الاقواس أو طباعة التعبري هكذا:.degrees/2/pi خشصيا ل أهجد نفيس بتذكر أولوية ابيق املؤثرات فان مل أكن واثقا اس تعملت الاقواس. انلارف معليات 2.8 يف العموم ل معليات حسابية تطبق عىل انلارف حىت و ان بدا احلرف كرمق فلك ما ييل غري قانوين: '2'-'1' 'eggs'/'easy' 'third'*'a charm' املؤثر + يس تخدم مع انلارف لكنه ل يعمل كام تظن: بل يقوم ابلضافة أي أنه جيمع حمارفني بوصلهام طرفا لطرف اكلتايل: first = 'throat' second = 'warbler' print first + second انجت هذا الربانمج هو.throutwarbler املؤثر * يعمل أيضا عىل انلارف ا ل أنه يقوم ابلتكرار مفثال * 3 'spam' ستصبح 'spamspamspam' عند اس تخدام املؤثر * فان واحدا من عاميل العملية جيب أن يكون عددا حصيحا.
فكر بايثون 16 تشاب ه اس تخدام املؤثران * و + عىل انلارف و عىل العداد مربر فكام أن 3*4 تساوي 4+4+4 سنتوقع أيضا أن spam*3 س تكرر spam ثالث مرات أي 'spam' 'spam' + 'spam' + و هو ما نتج. ابملقابل هناك فرق كبري بني التكرار و الضافة للمحارف و بني امجلع و الرضب للعداد هل تس تطيع التفكري خباصية للجمع ل تشبه الضافة احلوايش 2.9 لكام تضخم الربانمج و ازداد تعقيدا أصبحت قراءته و فهمه أصعب. فاللغات الرمسية كثيفة و غالبا ل يكفي جمرد النظر اىل نص برجمي لفهم ما هو و ما الغاية منه. لهذا السبب فان اضافة تعليقات اىل الربانمج تفرس بلغة طبيعية ما اذلي يفعهل تعترب فكرة جيدة. هذه التعليقات تسمى حوايش و تس هتل ابلرمز #: # compute the percentage of the hour that has elapsed percentage = (minute * 100) / 60 يف هذه احلاةل ظهرت احلاشية يف سطر لوحدها. ابماكنك وضع احلاشية يف هناية السطر الربجمي: percentage = (minute * 100) / 60 #percentage of an hour لك ما بعد # و اىل اخر السطر هممل لن يؤثر يف سري الربانمج. فائدة احلوايش تمكن يف تفسريها خلصائص الربانمج املهبمة فافرتاض أن من يقرأ الربانمج سيعرف "ما" اذلي يقوم به مفهوم املفيد هو تفسري "ملاذا" يقوم به. احلاشية التالية ثرثرة و ل فائدة لها: احلاشية التالية حتتوي عىل معلومات مفيدة و ليست ظاهرة يف النص الربجمي: v = 5 v = 5 # assign 5 to v # velocity in meters/second تسمية املتغريات احلكمية تقلل من احلاجة اىل احلوايش يف املقابل فالسامء الطويةل جتعل التعبريات املعقدة عصية عىل الفهم ذلا فهناكل حاجة للمفاصةل. عالج الاخطاء 2.10 يف هذه املرحةل س تكون الخطاء الكتابية اليت س تقرتفها يف الغلب أسامء املتغريات الغري جائزة ك اليت يه لكامت حمجوزة أو ك odd~job و us$ حتتوي عىل حروف غري قانونية. و class املشلكة اليت يراها ابيثون عندما تضع فراغا بني لكمتني من امس املتغري يه أنه يظن أهنام عاملني بدون مؤثر بيهنام: yield >>> bad name = 5 SyntaxError: invalid syntax عندما تظهر رسائل وجود خطأ حنوي فان الرساةل حبد ذاهتا ل تدل عىل اخلطأ نفسه و ل تساعد كثريا يف حهل. أكرث الرسائل ش يوعا يه: SyntaxError: invalid syntax و SyntaxError: invalid token والكهام ليس مفيدا جدا. رسائل اخلطأ اليت تظهر وقت التشغيل عىل الاغلب تقول "اس ت خدم قبل التعريف" مما يعين أنك حتاول اس تخدام متغري مل
تع ني هل قمية بعد هذا اخلطأ س يحدث ايضا عندما ختطئ هتجة امس املتغري: فكر بايثون 17 >>> principal = 327.68 >>> interest = principle * rate NameError: name 'principle' is not defined اسامء املتغريات تتغري بتغري حاةل احلروف )كبرية ام صغرية( ف LaTeX ليست Latex أكرث الخطاء ادلللية اليت سرتتكهبا يف هذه املرحةل عىل الارحج س تكون تراتب العمليات. مثال عندما حتاول تقيمي تكتب التعبري هكذا: 1 2π قد >>> 1.0 / 2.0 * pi و مبا أن القسمة يه الاولوية هنا حفاصل هذه العملية س يكون 2/π و هو ليس ما قصدت! ابيثون ل يعمل ما هو قصدك و ل يعمل أ ن هذه النتيجة ختتلف عام توقعت ذلكل لن يصدر أي رساةل تفيد بوجود خطأ فقط س تحصل عىل اجابة خاطئة. 2.11 املعاين قمية :value من وحدات البياانت الاساس ية اكلرمق و انلارف اليت ميكن لربانمج اس تخداهما. منط :type فئة من القمي. المناط اليت رأيهنا حىت الان اكنت أعداد حصيحة ( منط )int و أعداد النقطة العامئة أو الاعداد احلقيقية )منط )float و انلارف )منط.)str عدد حصيح :integer منط ميثل الاعداد بدون كسور. نقطة-عامئة :floating-point منط ميثل الاعداد مع كسورها. حمارف :string منط ميثل تسلسل من احلروف و الارقام و الرموز القانونية. متغري :variable أمس يشري لقمية. عبارة :statement جزء من النص الربجمي ميثل أمر أو فعل. العبارات اليت مرت بنا حىت الان اكنت تعيينات و.print تعيني :assignment أي عبارة تعني قمية ملتغري. رمس احلاةل :state diagram رمس بياين ميثل مجموعة من املتغريات و القمي اليت تؤرش الهيا. لكمة مفتاحية :keyword أسامء حمجوزة املفرس فقط يس تطيع اس تخداهما للتعرف عىل بناء الربانمج و ل ميكنك اس تخداهما لتسمية املتغريات الاسامء انلجوز ك def, if, while و غريها. املؤثر :operator رمز ميثل حوس بة بس يطة اكمجلع و الرضب أو اضافة انلارف. العامل :operand احدى القمي اليت يؤثر فهيا مؤثر العملية. قسمة أرضية :floor division القسمة اليت حتتفظ بأكرب عدد حصيح من الناجت و ت سقط البايق. تعبري :expression تركيبة من املتغريات و املؤثرات و القمي حمصلته قمية وحيدة. تقيمي :evaluate تبس يط التعبري عن طريق القيام ابلعمليات ليك حنصل عىل قمية وحيدة. قوانني الاولوية :rules of precedence مجموعة القوانني اليت حتمك الرتتيب اذلي ستنفذ هبا معليات فهيا مجموعة من العوامل
فكر بايثون 18 و املؤثرات ليك حنصل عىل النتيجة الهنائية. الاضافة :concatenate مجع انلارف طرف لطرف. حاشية :comment معلومة عن الربانمج موهجة للمربجمني )أو من يقرأ النص الربجمي( ل يكون لها تأثري عىل سري الربانمج. 2.12 مترين متارين width = 17 height = 12.0 delimiter = '.' 2.2 افرتض أننا نف ذان عبارة التعيني التية: اكتب القمية و المنط )منط قمية التعبري( للك من التعبريات التالية: اس تخدم مف رس ابيثون للتأكد من اجاابتك. مترين 1. width/2 2. width/20 3. height/3 4. 1 + 2 * 5 5. Delimiter * 5 2.3 تدرب عىل اس تخدام مف رس ابيثون كحاسبة..1.2 4 جحم كرة نصف قطرها r هو مفا هو جحم كرة نصف قطرها 5 )تلميح: جحمها ليس 392.7( 3 r3 π افرتض أن سعر كتاب للمس هتكل هو $24.95 الا ان املكتبة حتصل عىل ختفيض %40 رسوم الشحن لول نسخة مث 75 سنت للك نسخة اضافية مفا يه التلكفة اللكية ل 60 نسخة $3.3 ان غادرت مزنيل الساعة 6:52 صباحا للركض فركضت أول ميل برسعة منخفضة )8:15 للميل( مث ثالثة أميال برسعة أعىل )7:12 للميل( مث ميال اخر برسعة منخفضة فمك تكون الساعة عند عوديت اىل البيت لالفطار
فكر بايثون 19 الفصل الثالث الاقرتاانت نداء الاقرتاانت 3.1 يف الس ياق الربجمي فان الاقرتان هو تسلسل لعبارات تقوم بعملية حوسبة و يكون هل امس. عندما ت ع رف اقرتان فانك تعرف امسه و تسلسل العبارات. مث فامي بعد تنادي الاقرتان ابمسه. لقد مر علينا مثال لنداء اقرتان: امس هذا الاقرتان اكن نوع القرينة. >>> type(32) <type 'int'>. type القول الشائع هو ان الاقرتان "يأخذ" قرينة أو انه التعبري املوجود بني القوسني يسمى القرينة )قرينة الاقرتان( النتيجة )لهذه الاقرتان( اكنت "ي رجع" نتيجة. النتيجة تدعى القمية امل رجعة. تغيري الامناط اقرتاانت 3.2 دلى ابيثون اقرتاانت جاهزة حتول القمي من منط اىل منط اخر. اقرتان اس تطاع و ال فسيتذمر: int يأخذ أي قمية و حيولها ان عدد حصيح اىل >>> int('32') 32 >>> int('hello') ValueError: invalid literal for int(): Hello ابماكن int حتويل قمي العداد احلقيقية اىل اعداد حصيحة. لكنه ل يقرب النتيجة بل حيذف الكسور: >>> int(3.9999) 3 >>> int(-2.3) -2 أما float فيحول الاعداد الصحيحة و انلارف اىل أعداد حقيقية: و أخريا str حيول قرينته اىل حمارف: >>> float(32) 32.0 >>> float('3.14159') 3.14159 >>> str(32) '32' >>> str(3.14159) '3.14159'
ط 2 3.3 الاقرتاانت الرايضية فكر بايثون 20 دلى ابيثون مديول للرايضيات به معظم الاقرتاانت الرايضية املعروفة. املديول module هو ملف حيتوي عىل اقرتاانت عديدة تكون ذات صةل. قبل ان نمتكن من اس تخدام املديول علينا اس ترياده: هذه العبارة تس تدعي املديول و تضيف لربانجمك اكئن م ديول >>> import math امسه math ان طبعت امل دي ول س تظهر كل معلومات عنه: >>> print math <module 'math' (built-in)> حيتوي اكئن املديول عىل الاقرتاانت و املتغريات املع رفة يف املديول ليك تس تخدم أحد الاقرتاانت عليك حتديد امس املديول و كذكل امس الاقرتان مفصولن بنقطة )period( هذه الصياغة تدعى التنويت ابلنقاط. dot notation املثال الاول يس تخدم اقرتان >>> ratio = signal_power / noise_power >>> decibels = 10 * math.log10(ratio) >>> radians = 0.7 >>> height = math.sin(radians) signal_to_noise ابدلس بل )عىل فرض أننا ع رفنا أيضا به log اذلي حتسب لوغارمتات القاعدة e. log10 )noise_power و signal_power حلساب نسبة. مديول math املثال الثاين يوجد جيب الزاوية ادلائرية تعم دت جعل امس املتغري )radians( للتذكري بأن اقرتاانت حساب املثلثات ( cos, tan اخل( تعمتد الزوااي ادلائرية. لتحول الزاوية من درجات اىل دائري قس م القمية عىل 360 مث ارضب الناجت ب : >>> degrees = 45 >>> radians = degrees / 360.0 * 2 * math.pi 0.707106781187 الرتكيب 3.4 ما رأيناه حىت هذه الن هو عنارص الربانمج من متغريات و تعابري و عبارات منعزةل دون التحدث عن طرق امجلع بيهنا. من اكرث وظائف لغات الربجمة فائدة يه قدرهتا عىل أخذ لبنات بناء صغرية و تركيهبا.)compose( فقرينة الاقرتان عىل سبيل املثال قد تكون أي من التعبريات حىت أن املؤثرات احلسابية قد تصبح قرائن: و قد يكون نداء اقرتان حبد ذاته قرينة: x = math.sin(degrees / 360.0 * 2 * math.pi) x = math.exp(math.log(x+1)) ميكنك وضع قمية يف أي موقع تقريبا ميكنك وضع تعبري ابلغ التعقيد ابس تثناء وحيد: الطرف الايرس لعبارة تعيني جيب أن يكون امس املتغري أي تعبري اخر عىل يسار التعيني س يعترب خطأى حنواي )سرنى الاس تثناءات يف هذا املضامر لحقا(. >>> minutes = hours * 60 #right >>> hours * 60 = minutes #wrong! SyntaxError: can't assign to operator
3.5 اضافة اقرتاانت جديدة فكر بايثون 21 ما اس تخدمناه حلد الان يه اقرتاانت جاهزة أتت مع ابيثون الا انه ابماكننا معل اقرتاانت جديدة تضاف اىل الربانمج. تعريف الاقرتان حيدد امس الاقرتان اجلديد و العبارات اليت ستنفذ عند نداء هذا الاقرتان. هذا مثال: def print_lyrics(): print I'm a lumberjack, and I'm okay print I sleep all night and I work all day print_lyrics. قوانني تسمية الاقرتاانت اللكمة املفتاحية def تشري اىل ان هذا تعريف لقرتان امس الاقرتان يه نفسها قوانني تسمية املتغريات: حروف و أرقام و بعض العالمات القانونية الاخرى و أيضا جيب الا يس هتل الامس برمق و ل جيوز اس تخدام اللكامت املفاتيح كسامء لالقرتاانت و الفضل جتنب اس تخدام نفس المس ملتغري و لقرتان. القوسان الفارعان )( بعد الامس تشريان اىل ان هذا القرتان ل يأخذ قرينة. السطر الاول من تعريف الاقرتان يسمى الرتويسة header و ابيق التعريف يسمى ا نتمل )body(. جيب أن تنهتيي الرتويسة بنقطتان :. جيب أن تكون هناك مسافة ابدئة لسطور منت الاقرتان امجع املربجمون أن تكون أربعة فراغات )انظر القسم 3.14(. ميكن ملنت الاقرتان ان حيتوي عىل أي عدد من العبارات. يف هذا الاقرتان اكنت انلارف حماطة بعالمات اقتباس مزدوجة العالمة املزدوجة و العالمة املفردة تقومان بنفس اليشء أغلب الناس يس تخدمون العالمة املفردة ال ان تطلب الامر اس تخدام املزدوجة فالعالمة املفردة يه أيضا عالمة اختصار ابلجنلزيية ك cannot(.)can't = فان احتوت امجلةل املطبوعة عىل عالمة اختصار ت ستعمل العالمة املزدوجة. ان طبعت تعريف اقرتان يف الوضع التفاعيل فان املف رس س يطبع نقاط انلذوف )ثالث نقاط متتالية كتكل اليت يف "امل الفراغ" ) ليك ينهبك اىل ان الاقرتان غري مكمتل: >>> def print_lyrics():... print I'am lumberjack, and I'm okay... print I sleep all night and I work all day... يف الوضع التفاعيل فقط جيب ادخال سطر فارغ ليك ختمت الاقرتان و ليس رضوراي يف وضع كتابة النص. تعريف الاقرتان يوجد متغريا بنفس الامس: قمية print_lyrics يه اكئن اقرتان و لها المنط اقرتان حنو كتابة نداء الاقرتان اجلديد هو نفس حنو الاقرتاانت اجلاهزة: >>> print print_lyrics <function print_lyrics at 0x6d88ce9a> >>> type(print_lyrics) type 'function'.)function( >>> print_lyrics() I'm lumberjack, and I'm okay I sleep all night and I work all day. مبجرد تعريفك لقرتان ميكنك اس تخدامه من داخل اقرتان أخر. جديد ينادي اقرتاننا احلايل مرتني: مفثال ان اردان تكرار امجللتني السابقتني نس تطيع كتابة اقرتان def repeat_lyrics():
فكر بايثون 22 print_lyrics() print_lyrics() >>> repeat_lyrics() I'm lumberjack, and I'm okay I sleep all night and I work all day I'm lumberjack, and I'm okay I sleep all night and I work all day مث ننادي :repeat_lyrics يف الواقع ل تغىن هذه الاغنية هكذا. 3.6 التعريفات و اس تخداماهتا ان مجعنا فتات النص الربجمي من القسم السابق فان الربانمج اللكي سيبدو اكلتايل: حيتوي هذا الربانمج عىل اقرتانني: الاخرى لكن تأثريها هو خلق اكئن اقرتان الاقرتان ل يودل أية خمرجات. مترين def print_lyrics(): print I'am lumberjack, and I'm okay print I sleep all night and I work all day def repeat_lyrics(): print_lyrics() print_lyrics() repeat_lyrics() و repeat_lyrics تنفذ الاقرتاانت كام تنفذ العبارات العبارات املوجودة داخل الاقرتان ل تنفذ الا اذا نودي الاقرتان تعريف print_lyrics 3.2 كام تتوقع فال ميكن تنفيذ اقرتان قبل خلقه بلكامت اخرى جيب تنفيذ تعريف الاقرتان قبل ندائه للمرة الاوىل. مترين 3.1 يف الربانمج السابق انقل السطر الاخري اىل بداية النص الربجمي حبيث تظهر عبارة نداء الاقرتان قبل التعريفات مث شغل الربانمج و لجظ رسائل الاخطاء. انقل نداء الاقرتان اىل ماكهنا الاصيل مث انقل التعريف ماذا تتوقع أن حيدث عند تشغيل الربانمج repeat_lyrics print_lyrics ما قبل اىل رساين التنفيذ 3.7 ليك تضمن بأن الاقرتان معرف قبل اس تخدامه عليك ان تعرف الرتتيب اذلي يمت وفقه تنفيذ العبارات و هو ما يسمى رساين التنفيذ.flow of execution يبدأ التنفيذ دامئا بأول عبارة يف الربانمج تنفذ العبارات واحدة تلو الاخرى من العىل اىل السفل. تعريفات الاقرتاانت ل تؤثر يف هذا الرتتيب لكن تذكر بأن العبارات املوجودة داخل الاقرتان لن تنفذ قبل نداء الاقرتان. يف ترتيب رساين الربانمج يشبه نداء الاقرتان التحويةل فبدل من الانتقال اىل العبارة التالية يف الرتتيب فان الرساين س يقفز اىل منت الاقرتان املنادى و ينفذ لك العبارات هناك مث يعود اىل املوضع اذلي قفز منه. قد يبدو هذا بس يطا اىل تتذكر بأن اقرتان ما ميكنه نداء اخر فبيامن يكون الربانمج يف وسط اقرتان ما قد يتطلب نداء عبارة
فكر بايثون 23 من اقرتان اخر بل انه قد يتطلب نداء اقرتان اثلث بيامن هو يف الاقرتان الثاين. حلسن احلظ ابيثون يتذكر جيدا من أين انطلق يف القفزة الاوىل ففي لك مرة ينهتيي من تنفيذ اقرتان يقفز عائدا اىل النقطة اليت نودي الاقرتان مهنا و يمكل و عندما يصل اىل هناية الربانمج ينقيض. ما العربة الاخالقية من هذه احلاكية يه أنه عندما تقرأ برانجما فأنت لست مضطرا لقراءة النص من الاعىل اىل الاسفل بل من املنطقي أن تتبع ترتيب رساين الربانمج. 3.8 الربمرتات و القرائن بعض الاقرتاانت اجلاهزة اليت رأيناها تتطلب قرائن فعندما تنادي math.sin عليك مترير رمق ما كقرينة بعض الاقرتاانت تتطلب أكرث من قرينة math.pow تتطلب قرينتني مثال. داخل الاقرتان ت عني هذه القرائن ملتغريات تدعى برمرتات هذا مثال لقرتان أوجده املس تخدم يأخذ قرينة: def print_twice(bruce): print bruce print bruce هذا الاقرتان يعني قرينة لربمرت امسه. bruce عندما ينادى فس يطبع قمية الربمرت )بغض النظر ما هو( مرتني. و هذا الاقرتان يعمل مع أي قمية متكن طباعهتا. >>> print_twice('spam') Spam Spam >>> print_twice(17) 17 17 >>> print_twice(math.pi) 3.14159265359 3.14159265359 نفس قوانني الرتكيب اليت تنطبق عىل الاقرتاانت اجلاهزة تنطبق أيضا عىل اقرتاانت املس تخدم. فباماكننا اس تخدام أي نوع من العبارات كقرينة ل :print_twice ت ق مي القرينة قبل نداء الاقرتان ففي الامثةل السابقة أأوجدت قمي واحدة. ميكنك أيضا اس تخدام متغريات كقرائن: و >>> print_twice('spam'*4) Spam Spam Spam Spam Spam Spam Spam Spam >>> print_twice(math.cos(math.pi)) -1.0-1.0 math.cos(math.pi) 'Spam' *4 مرة >>> michael = 'Eric, the half of bee.' >>> print_twice(michael) Eric, the half of bee. Eric, the half of bee. michael print_twice امس املتغري اذلي مررانه كقرينة لالقرتان اكن و ل عالقة هل ابمس الربمرت) bruce ( اذن ل هيم أي قمية انديناها لتعود اىل مزنلها )يف املنادي(. فنحن يف هذه الاقرتان ندعو لك الناس "أبو رشيك".bruce
3.9 املتغريات و الربمرتات موضعية فكر بايثون 24 عندما توج د متغريا داخل اقرتان فانه يكون موضعيا )حمليا( أي أنه يوجد فقط داخل الاقرتان مثال: يأخذ هذا الاقرتان قرينتني جيمعهام مث يطبع النتيجة هذا مثال لس تخدامه: عندما ت غ قل def cat_twice(part1,part2): cat = part1 + part2 print_twice(cat) >>> line1 = 'Bing tiddle ' >>> line2 = 'tiddle bang' >>> cat_twice(line1, line2) Bing tiddle tiddle bang Bing tiddle tiddle bang cat فان cat_twice الربمرتات كذكل موضعية خفارج حدود سيتلف و ان حاولنا طباعته س نحصل عىل اس تثناء: >>> print cat NameError: name 'cat' is not defined print_twice ل معىن ل.bruce الشلك 3.1: الرمس املستف 3.10 الرمس املس تف: stack diagram لتمتكن من مالحقة أين املتغريات و أماكن اس تخداهما من املفيد أحياان معل رمس مستف. كام رمس احلاةل الرمس املستف يبني قمية لك من املتغريات ابلضافة ذلكل فهو يبني الاقرتان اليت ينمتي اليه ذكل املتغري. ميث ل لك اقرتان ابطار الاطار هو صندوق يكتب اىل جانبه امس الاقرتان و بداخهل اسامء برمرتات و متغريات الاقرتان الرمس املستف للمثال السابق يظهر يف الشلك 1.3. ترتب الاطارات يف الرمس املستف عىل شلك تكديسة تبني أي اقرتان اس تدعى أي اقرتان اخر. يف مثالنا هذا اكن اذلي اس تدعى print_twice هو cat_twice أما cat_twice فقد اس تدعاه main و هو امس خمص وص لالطار املوجود يف مقة التستيفة عندما ختلق متغريا خارج أي اقرتان فانه ينمتي اىل main. لك برمرت يف الاقرتان يشري اىل نفس قمية قرينته ف.cat نفس قمية bruce part1 هل نفس قمية كذكل part2 line1 و ل line2 و ان ظهر خطأ عند نداء الاقرتان فس يطبع ابيثون امس الاقرتان و الاقرتان اليت اس تدعاه و امس الاقرتان اذلي اس تدعى الاقرتان اذلي اس تدعاه و هكذا حىت تصل اىل main.
مفثال عندما حتاول النفاذ اىل cat من داخل فكر بايثون 25 print_twice س تحصل عىل :NameError Traceback (innermost last): file testpy, line 12, in main cat_twice(line1, line2) file testby, line 5, in cat_twice print_twice(cat) file testpy, line 9, in print_twice print cat NameError: name 'cat' is not defined قامئة الاقرتاانت هذه تسمى "املالحقة".traceback ويه تقول كل يف أي من ملفات الربانمج وقع اخلطأ و يف أي سطر و كذكل يبلغك ابلقرتاانت اليت اكنت تنفذ حني وقوع اخلطأ و تظهر كذكل السطر الربجمي اذلي سبب اخلطأ. تراتب الاقرتاانت يف املالحقة هو نفس الرتاتب املوجود يف الرمس املس تف فالقرتان املنشغل حاليا يقبع يف الاسفل. 3.11 الاقرتاانت املمثرة و الاقرتاانت العقمية بعض الاقرتاانت اليت بني يدينا اكلقرتاانت احلسابية تؤيت بنتيجة و لعدم وجود امس أفضل مسيهتا "اقرتاانت ممثرة" الاقرتاانت الاخرى ك print_twice اليت تقوم بعملية ما لكهنا ل ترجع قمية هذه الاقرتاانت تسمى عقمية.void انت يف أغلب الاحوال تنادي اقرتان ممثر ليك تس تخدم مثرته مفثال قد تعني نتيجة الاقرتان ملتغري ما أو تس تخدم النتيجة يف تعبري: عند نداء الاقرتان يف الوضع التفاعيل فان ابيثون س يظهر النتيجة: القمية لكن يف وضع كتابة النص عندما تنادي اقرتان ممثر كام هو فان نتيجته س تفقد اىل الابد! يقوم النص حبساب اجلذر الرتبيعي ل 5 لكن طاملا أهنا مل تطبع أو ختزن فاهنا تصبح عدمية الفائدة. x = math.cos(radians) golden = (math.sqrt(5) + 1) / 2 >>> math.sqrt(5) 2.2360679774997898 Math.sqrt(5) قد تعرض الاقرتاانت العقمية شيئا عىل الشاشة أو تقوم بتأثري ما لكهنا ل ترجع قمية فان حاولت تعيني نتيجة اقرتان عقمي ملتغري فس تحصل عىل خاصة تسمى "عدم".None >>> result = print_twice('bing') Bing Bing >>> print result None None ليست انلارف 'None' و يه أيضا قمية لها منطها اخلاص :None مجيع الاقرتاانت اليت كتبناها حىت الان يه اقرتاانت عقمية سنبدأ بكتابة اقرتاانت ممثرة بعد بضعة فصول. >>> print type(none) <type 'NoneType'> 3.12 الاقرتاانت ملاذا قد ل تكون الفائدة من حتمل عناء تقسمي الربانمج اىل اقرتاانت جلية بعد. حس نا هناكل عدة اسباب:
فكر بايثون 26 معل اقرتان جديد ميكنك من تسمية عدة عبارات مكجموعة واحدة مما يسهل قراءة و عالج اخطاء الربانمج. ابماكن الاقرتاانت تصغري جحم الربانمج حيث أهنا تقلل من تكرار النص الربجمي مث عندما تريد تعديل النص لحقا س يكون عليك تعديهل يف موضع واحد. تقسمي برانمج طويل اىل اقرتاانت ميك نك من عالج أخطاء الجزاء واحدا بعد الاخر مث جتميعها لتعمل يف الهناية كلك. الاقرتاانت املصممة جيدا مفيدة لكرث من برانمج فمبجرد كتابتك لقرتان و عالجك لخطائه تس تطيع اس تخدامه يف ماكن اخر. >>> import math >>> print math <module 'math' (built-in)> >>> print math.pi 3.14159265359 pi math 3.13 الاس ترياد ابس تخدام from يزودك ابيثون بطريقتني لس ترياد املديولت رأينا مهنام: عندما تس تورد اقرتاانت ك math.exp و sin ال انك عندما حتاول الوصول فانك توجد يف برانجمك اكئن مديول يسمى حيتوي هذا الاكئن عىل ثوابت ك و >>> print pi اىل pi مبفردها س تحصل عىل خطأ: البديل هو أن تس تورد Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> print pi NameError: name 'pi' is not defined >>> pi عندها ميكنك اس تخدام pi مبارشة: فقط من مديول : math أو أنك تس تورد لك ما يف املديول ابس تخدام الرمز *: >>> from math import pi >>> print pi 3.14159265359 >>> from math import * >>> cos(pi) -1.0 فائدة اس ترياد لك يشء من املديول يه أن النص الربجمي يصبح موجزا س يئهتا هو احامتل وجود تشابه يف الاسامء املعر فة يف املديولت اهلتلفة أو بني امس يس تعمهل املديول و امس تس تعمهل انت يف برانجمك.
عالج الاخطاء 3.14 فكر بايثون 27 اس تخدام حمرر نصوص عادي لكتابة النصوص الربجمية لبايثون قد يسبب الخطاء خصوصا ابلنسبة للمسافات البادئة افضل طريقة لتجنب هذه الخطاء هو اس تخدام الفراغات املفردة و ليس فراغات اجلدوةل )TABS( معظم حمررات النصوص اليت مسعت ببايثون تقوم بوضع املسافات اليا. الفراغات و مسافات اجلدوةل غري مرئية مما يصعب عالج الخطاء النامجة عهنا ذلكل حاول العثور عىل حمرر نصوص يقوم هبا اليا. ل تنس حفظ برانجمك قبل تشغيهل بعض انلررات ختزنه كل عندما تطلب تشغيهل اخلطأ انلمتل هنا هو أنك شغلت برانجما غري اذلي تنظر اليه يف حمرر النصوص. قد يس هتكل عالج الخطاء الكثري من الوقت عندما تعتقد بأن الربانمج اذلي شغلته هو الربانمج اذلي تنظر اليه يف انلرر. مفهام عدلت يف انلرر س تحصل عىل نفس اخلطأ مرارا و تكرارا. ان مل تكن متأكدا من أن النص الربجمي يف انل رر هو اذلي يعمل عندما تشغل الربانمج ادرج عبارة يف النص الربجمي ك 'hello' print فان مل تر Hello يف الربانمج س تعمل بأنك تشغل برانجما اخر. املعاين 3.15 اقرتان :function مجموعة من العبارات اليت تنفذ معلية مفيدة ما تكون حتت مسمى واحد. الاقرتاانت قد تأخذ قرائن أو قد ل تأخذ و قد تعود بنتيجة أو ل. تعريف اقرتان :function definition عبارة تنشئ اقرتاان جديدا حتدد هل امس و برمرتات و كذكل عبارات ينفذها. اكئن الاقرتان :function object قمية أنتجها تعريف الاقرتان. فامس الاقرتان هو متغري يشري اىل ترويسة :header أول سطر يف تعريف الاقرتان. منت :body سلسةل العبارات املوجودة داخل تعريف الاقرتان. برمرت :parameter امس يس تخدم داخل الاقرتان. يشري اىل القمية اليت مررت كقرينة. نداء الاقرتان :function call عبارة تنفذ الاقرتان. تتألف من امس الاقرتان يتبعه سلسةل من القرائن. قرينة :argument قمية مترر اىل الاقرتان عند ندائه. و هذه القمية تعني متغري موضعي القمية املرجعة للربمرت املقصود. اكئن الاقرتان. :local variable هو متغري عر ف داخل اقرتان. املتغري املوضعي يستعمل فقط داخل الاقرتان. :return value نتيجة الاقرتان. ان اس ت خدم نداء الاقرتان كتعبري فان القمية املرجعة يه قمية التعبري. اقرتان ممثر :fruitful function اقرتان يعود بقمية. اقرتان عقمي :void function اقرتان ل يعود بقمية. مديول :module ملف حيتوي عىل تشكيةل من الاقرتاانت و غريها من التعريفات. تكون من نفس املوضوع. عبارة الاس ترياد :import statement عبارة تقرأ ملف املديول و ختلق اكئن مديول. اكئن مديول :module object القمية اليت أنشأهتا عبارة الاس ترياد import تسمح هذه القمية ابلوصول اىل القمي املوجودة يف املديول.
التنويت ابلنقط :dot notation بنقطة مث امس الاقرتان. فكر بايثون 28 تركيبة اعراب تس تخدم لنداء اقرتان من داخل ملف مديول بأن تكتب امس املديول تتبعها الرتكيب :composition اس تخدام تعبري كجزء من تعبري أكرب أو عبارة كجزء من عبارة أكرب. رساين التنفيذ :flow of execution ترتيب تنفيذ العبارات خالل تشغيل الربانمج. الرمس املستف :stack diagram متثيل صوري لرصة من الاقرتاانت و متغرياهتا و القمي اليت تشري الهيا. اطار :frame صندوق مرسوم يف الرمس املستف ميثل نداءا لقرتان. تكتب فيه املتغريات املوضعية و قميها. املالحقة :traceback قامئة ابلقرتاانت اليت تنفذ حاليا تطبع هذه القامئة عند حدوث اس تثناء. 3.16 مترين متارين 3.3: دلى ابيثون اقرتاان جاهزا يسمى len ي رجع طول انلارف فقمية len('allen'( يه 5 اكتب اقرتاان و مسه right_justify يأخذ حمارف امسها حبيث يكون اخر حرف من s يف العمود 70 من الشاشة. s كربمرت مث يطبع ما يكفي من الفراغات قبل انلارف s >>> right_justify('allen') allen مترين 4.3: اكئن اقرتان يه قمية ميكنك تعييهنا ملتغري او متريرها كقرينة مثال كقرينة و يناديه مرتني: هذا مثال لس تخدام do_twice لنداء اقرتان امسه do_twice هو اقرتان يأخذ اكئن اقرتان def do_twice(f): f() f() print_spam مرتني: dif print_spam(): print 'spam' do_twice(print_spam).1.2.3.4.5 اكتب املثال يف نص برجمي مث جربه. عدل do_twice حبيث يأخذ قرينتني اكئن اقرتان و قمية و ينادي الاقرتان مرتني ممررا القمية كقرينة. اكتب صيغة أمع من print_spam و مسها print_twice حبيث تأخذ حمارف كربمرت مث تطبعها مرتني. اس تخدم الصيغة املعدةل من do_twice حبيث تس تدعي print_twice و مترر لها 'spam' كقرينة. عرف اقرتاان جديدا و مسه do_four حبيث يأخذ اكئن اقرتان و قمية و ينادي الاقرتان أربعة مرات ممررا هل القمية كربمرت عىل أن تكون يف منت الاقرتان عبارتني فقط و ليس اربعة. احللول:.http://thinkpython.com/code/do_four.py مترين 3.5 ميكنك حل هذا المترين ابس تخدام العبارات و خصائص ابيثون اليت مرت علينا حىت الان: اكتب اقرتاان يرمس ش بكة كهذه:
فكر بايثون 29 تلميح: لتطبع أكرث من قمية عىل سطر واحد اطبع تسلسال مقسام بفاصةل: + - - - - + - - - - + + - - - - + - - - - + + - - - - + - - - - + Print '+', '-' عندما ينهتيي التسلسل بفاصةل فان ابيثون يرتك السطر غري مهنيي و هكذا فالقمية اليت طبعت بعده تظهر عىل نفس السطر. ما س ينتج من هذه العبارات هو '- Print '+', print '-' أما عبارة print لوحدها فستهنيي السطر و تنتقل للسطر التايل. '+ اكتب اقرتاان اخر يرمس نفس الش بكة لكن بأربعة صفوف و اربعة امعدة. احللول:.http://thinkpython.com/code/grid.py والني برجمة يس العملية الاصدار الثالث أورييل ميداي 1997. عرفان: بين هذا المترين عىل مترين يف كتاب
فكر بايثون 30 الفصل الرابع دراسة حاةل: تصممي الواهجة أمثةل النص الربجمي لهذا الفصل متوفرة عىل http://thinkpython.com/code/polygon.py عامل السلحفاة 4.1 كتبت رزمة برجمية لرتافق هذا الكتاب و مسيهتا Swampy ابماكنك حتميل سوميب من http://thinkpython.com/swampy الرزمة يه مجموعة من املديولت احدى املديولت يف سوميب يه لرتمس خطوطا عن طريق قيادة سالحف عىل الشاشة. ان كنت قد نص بت سوميب كرزمة فباماكنك اس تريادها هكذا: مث اتباع التعلاميت هناك لتنصيهبا يف نظام التشغيل. TurtleWorld توفر كل مجموعة من الاقرتاانت from swampy.turtleworld import * اما ان كنت قد محلت مديولت سوميب و مل تنصهبا كرزمة فباماكنك ا ما اس تخداهما يف املدل اذلي حيتوي ملفات سوميب او اضافة ذكل املدل اىل مسار حبث ابيثون. عندها ميكنك اس ترياد TurtleWorld هكذا: from TurtleWorld import * كيفية تنصيب و اعداد مسار البحث لبايثون تعمتد عىل أنظمة التشغيل. و لئال يزدمح الكتاب بتفاصيل غري ابيثون فضلت وضع تكل التعلاميت حول سوميب و انظمة التشغيل العديدة هنا: http://thinkpython.com/swampy انشئ ملفا جديدا و مسه السطر الاول سيس تورد لك ما يف mypolygon.py مث اطبع النص الربجمي التايل: from swampy.turtleworld import * world = TurtleWorld() bob = Turtle() print bob wait_for_user() مديول TurtleWorld من رزمة.swampy يف السطور التالية نوجد اقرتان TurtleWorldو نعينه ل world مث Turtle و نعينه ل bob طباعة bob س تنتج شيئا كهذا: هذا يعين بأن <TurtleWorld.Turtle object at 0xb7bfbf4c>.TurtleWorld bob يشري اىل جتلية instance من السلحفاة كام يه مع رفة يف مديول و معىن
instance فكر بايثون 31 هنا هو "عضو يف مجموعة" هذه السلحفاة يه واحدة من مجموعة السالحف املتوفرة يف املديول. wait_for_user هنا تأمر عامل السلحفاة بأن ينتظر حىت يقوم املس تخدم بيشء ما نعمل أن ليس هناك الكثري ليقوم به املس تخدم غري اغالق النافذة. يوفر عامل السلحفاة عدة اقرتاانت لقيادة السلحفاة: fd و bk اىل الامام و اىل اخللف lt و rt اىل اليسار و اىل الميني. لك سلحفاة حتمل قلام اما ان يكون مرفوعا أو موضوعا ان اكن موضوعا فس ترتك السلحفاة أثرا عند سريها. الاقرتاانت pu و pd تعين قلام مرفوعا و قلام موضوعا. لرتمس زاوية قامئة اضف السطور التالية )بني سطر اجياد bob و سطر fd(bob, 100) lt(bob) fd(bob, 100) bob :)wait_for_user السطر الاول يأمر bob ابلتقدم 100 خطوة السطر التايل يأمره الالتفاف يسارا. عند تشغيل الربانمج. سرتى يسري رشقا مث شامل اتراك قطعتني مس تقميتني خلفه. الان عدل الربانمج لرتمس مربعا ل تمكل من هنا حىت تتقنه! fd(bob, 100) lt(bob) تكرار بس يط 4.2 أغلب الظن انك كتبت شيئا اكلتايل )بدون اظهار نصوص اجياد السلحفاة و انتظار املس تخدم(: fd(bob, 100) lt(bob) fd(bob, 100) lt(bob) fd(bob, 100) mypolygon.py جيد ال انه ميكننا القيام بنفس اليشء لكن أوجز عن طريق عبارة مث شغهل اثنية: for اضف املثال التايل ل سرتى شيئا كهذا: for I in range(4): print 'Hello!' Hello! Hello! Hello! Hello! اكن هذا ابسط اس تخدامات عبارة for سرنى الكثري مهنا لحقا ال أن هذا املثال اكف ليجعكل تشطب ما كتبت لرمس املربع! ل تنتقل اىل التايل حىت ترمس املربع ابس تخدام.for
هذه عبارة for اليت ترمس مربعا: فكر بايثون 32 for I in range(4): fd(bob, 100) lt(bob) بناء عبارة for كبناء تعريفات الاقرتاانت فلها ترويسة تنهتيي بنقطتني مث املنت انلدد مبسافات ابدئة. للمنت ان حيتوي عىل اي عدد من العبارت. عبارة for تدعى احياان حلقة loop لن لن تنفيذ العبارات يدور عرب منت العبارة مث يعود اىل البداية يف حالتنا هذه فادلوران يف احللقة اكن لربعة مرات. هذه النسخة ختتلف عن سابقهتا لرمس املربع لن أخر ما ينف ذ هو الالتفاف اىل اليسار بعد رمس اخر ضلع للمربع. تأخذ هذه الالتفافة الاخرية بعضا من وقت الربانمج الا اهنا تبسط النص الربجمي ان كنا نقوم بنفس العمل لك دورة يف احللقة. و لهذه النسخة تأثري أخر فهيي ترتك السلحفاة يف موقع البداية ملتفتة اىل الاجتاه الاصيل. متارين 4.3 ماييل هو سلسةل متارين ابس تخدام. TurtleWorld املطلوب مهنا هو ان تكون ممتعة ال ان لها هدف ايضا. بيامن تعمل علهيا فكر مبا قد يكون هذا الهدف. يف الاقسام الالحقة هناكل حلول لهذه الامترين فال تنظر هناك حىت تنهتيي من حلها )او حاولت عىل الاقل(. 1. اكتب اقرتاان امسه square يأخذ برمرت امسه t اذلي س يكون السلحفاة عىل هذا الاقرتان ان يرمس مربعا ابس تخدام السلحفاة. اكتب عبارة نداء اقرتان حبيث مترر bob كقرينة ل square مث شغل الربانمج مرة اخرى. 2. اضف ل square برمرت اخر و مسه length عدل يف منت الاقرتان حبيث يكون طول الاضالع هو length مث عدل يف عبارة نداء الاقرتان حبيث حتتوي عىل قرينة اثنية شغل الربانمج مث جربه مبدى من القمي ل.length 3. الاقرتاانت lt و rt تقوم ابللتفاف 90 درجة اكعداد ابتدايئ الا انه ميكنك اضافة قرينة حتدد هبا درجات الالتفاف مثال:( 45 lt(bob, س تدير 45 bob درجة اىل اليسار. امعل نسخة من square و مسها polygonاضف لها برمرتا اخر امسه n مث عدل منت الاقرتان حبيث يرمس bob مضلعا عدد اضالعه n. تلميح: الزاوية اخلارجية ملضلع 360/n درجة. 4. اكتب اقرتاان امسه circle يأخذ السلحفاة t و نصف القطر r كربمرتات حبيث يرمس دائرة تقريبية عن طريق اس تدعاء polygon بعدد مناسب من الاضالع و بتعديل اطوالها جرب نصك بعدة قمي ل r. تلميح: تذكر حساب حميط ادلائرة مث تأكد من ان = length * n انليط. تلميح اخر: ان كنت ترى ان bob بطيء رس عه ابس تخدام bob.delay و هو الزمن بني لك حركة هل ابلثواين = 0.01 Bob.delay لتحركه برسعة. 5. امعل نسخة معممة اكرث من circle و مسها arc تأخذ القرينة الضافية angle اليت حتدد مقدار اجلزء اذلي سري مس من ادلائرة Angle مقاسة ابدلرجات فعندما تكون = 360 angle سريمس bob دائرة اكمةل.
الكبسةل 4.4 فكر بايثون 33 طلب منك يف المترين الاول وضع نص رمس املربع يف تعريف اقرتان مث نداء الاقرتان حبيث مترر السلحفاة كربمرت هنا حل املثال: def square(t): I in range(4): fd(t, 100) lt(t) square(bob) for العبارات املوجودة يف قلب الربانمج lt و fd مسافاهتا البادئة مضاعفة لتبني اهنا داخل حلقة و اليت بدورها داخل تعريف اقرتان. السطر التايل square(bob) كتب عىل بداية السطر أي أنه يهنيي لك من حلقة for و تعريف الاقرتان داخل الاقرتان t تشري اىل نفس السلحفاة ملاذا ل أمسي الربمرت bob الفكرة يه أن و متررها كقرينة ل :square أي أن lt(t) تعمل ك lt(bob) اذن فلامذا أحتمل العناء قد تكون أي سلحفاة و ليس فقط bob هذا ميكنك من اجياد سلحفاة اثنية ray = Turtle() square(ray) bob t تغليف قطعة برجمية يف اقرتان يسمى كبسةل من فوائد الكبسةل هو أهنا تلحق اسام ابلنص الربجمي مما خيدمك يف توثيق ما تكتبه من الاجياز نداء اقرتان مرتني بدل من قص و نسخ منت الاقرتان. التعممي 4.5 اخلطوة التالية يه اضافة الربمرت length اىل square هاك احلل: def square(t, length): for I in range(4): fd(t, length) lt(t) square(bob, 100) اضافة برمرت لقرتان يسمى تعمامي لنه جيعل الاقرتان يس تخدم لكرث من وظيفة: يف النسخة السابقة اكن لضالع املربع نفس الطول الطول يف هذه النسخة قد يكون بأي مقدار. اخلطوة اليت تيل يه أيضا تعممي فبدل من رمس مربع polygon يرمس مضلعا منتظام هل اي عدد من الاضالع تريد. هاك احلل: القانون def polygon(t, n, length): angle = 360.0/n for I in range(n): fd(t, length) lt(t, angle) polygon(bob, 7, 70) سريمس هذا النص س باعيا طول اضالعه 70 و ان اكن دليك اكرث من بضعة قرائن عددية فالسهل نس يان ما يه أو ما هو ترتيهبا من اجلائز و احياان من املفيد تضمني الربمرتات يف قامئة القرائن: polygon(bob, n=7, length=70) تسمى هذه لكامت مفتاحية قرينية لهنا تتضمن اسامء الربمرتات كلكامت مفاتيح )ل ختلط بيهنا و بني لكامت ابيثون املفتاحية ك
فكر بايثون 34.)def و while هذا الرتكيب يسهل قراءة الربانمج و ينبه للربمرتات. القرائن كيفية معل اىل كذكل و الربمرتات: فعند نداء الاقرتان تعني القرائن تصممي الواهجة 4.6 اخلطوة التالية يه أن تكتب مضلعا مخسيين: circle اليت تأخذ نصف القطر r كربمرت هاك حل بس يط يس تخدم polygon لرمس def circle(t, r): circumference = 2 * math.pi * r n = 50 length = circumference / n polygon(t, n, length) حيسب السطر الاول حميط ادلائرة اليت نصف قطرها r ابملعادةل 2 نق.ط و مبا أننا نس تخدم math.pi.math امجع املربجمون ان تكون عبارات import يف بداية النص الربجمي. n يه عدد القطع املس تقمية اليت تك ون دائرتنا التقريبية اذن r. مضلعا مخس ينيا ميثل تقريبا دلائرة نصف قطرها polygon length فعلينا اس ترياد يكون طول لك قطعة مس تقمية و هكذا سريمس لنا هناك تقييد واحد لهذا احلل هو أن n عدد اثبت مما يعين أنه عندما نرمس دائرة كبرية جدا س يكون طول القطع املس تقمية كبري و عندما نرمس دائرة صغرية جدا س نضيع الوقت برمس قطع مس تقمية صغرية. احلل الاوحد لهذا التقييد هو تعممي الاقرتان بأخذ n كربمرت و هكذا س نعطي حرية اكرث للمس تخدم )من يس تدعي circle أاي اكن( الا ان الواهجة س تكون اقل نظافة. واهجة اقرتان يه اجامل لكيفية اس تخدامه: ما يه الربمرتات ما اذلي يفعهل الاقرتان واهجة الاقرتان تكون "نظيفة" ان اكنت "بس يطة قدر الاماكن لكن ليس أبسط. )اينش تني(". يف هذا املثال تنمتي ادلائرة. r اىل الواهجة لهنا حتدد ادلائرة اليت سرتمس. أما n الافضل بدل من اعامم الفوىض يف الواهجة اختيار قمية مناس بة ل n حسب طول حميط ادلائرة: فليست مناسبة لهنا تتبع الكيفية اليت ستتجسد هبا def circle(t, r): circumference = 2 * math.pi * r n = int(circumference / 3) + 1 length = circumference / n polygon(t, n, length) هكذا س يصبح عدد القطع املس تقمية يساوي )تقريبا( ثلث حميط ادلائرة فيكون طول القطع املس تقمية )تقريبا( 3 و يه صغرية مبا يكفي حبيث تظهر ادلائرة كدائرة و كبرية مبا يكفي حبيث تكون فعاةل و مناس بة لي جحم من ادلوائر.
4.7 التفتيت و البناء فكر بايثون 35 عندما كتبت circle اكن بوسعي اس تخدام polygon مرة اخرى لن املضلع تقريب مقبول لدلائرة لكن الاقواس ليست متساهةل اكدلائرة فليس بوسعنا اس تخدام املضلع او ادلائرة لرمس القوس. حل بديل لهذا هو نسخ النص الربجمي ل polygon و حتويهل اىل نص لقوس قد تكون النتيجة اكلتايل: النصف الثاين من هذا الاقرتان يبدو مكضلع الا اننا لن نس تطيع اس تخدام نس تطيع تعممي polygon ليأخذ الزاوية كقرينة اثلثة الا ان الامس الصيغة الامع لالقرتان :polyline الان نعيد كتابة polygon و arc حبيث تس تخدما npolyline def arc(t, r, angle): arc_length = 2 * math.pi * r * angle / 360 n = int(arc_length / 3) + 1 step_length = arc_length / n step_angle = float(angle) / n for I in range(n): fd(t, step_length) lt(t, step_angle) polygon polygon من دون تعديل الواهجة قد لن يكون مناسبا! اذن لنسمي هذه def polyline(t, n, length, angle): for I in range(n): fd(t, length) lt(t, angle) def polygon(t, n, length): angle = 3600 / n polyline(t, n, length, angle) def arc(t, r, angle): arc_length = 2 * math.pi * r * angle / 360 n = int(arc_length / 3) + 1 step_length = arc_length / n step_angle = float(angle) / n polyline(t, n, step_length, step_angle) مث أخريا نعدل circle لتس تخدم :arc def circle(t, r): arc(t, r, 360) هذه العملية )اعادة ترتيب الربانمج لتحسني واهجات الاقرتاانت و تسهيل اعادة اس تخدام النص الربجمي( تدعى التفتيت و البناء.refactoring هنا لحظنا تشابه يف النص الربجمي لرمس قوس و ذكل لرمس املضلع ففتت نا نص املضلع و أعدان بناءه ليصبح قوسا. لو كنا قد خططنا مس بقا ملا اكن علينا التفتيت و البناء اكن الافضل لنا كتابة polyline منذ البداية لكننا يف الغالب ل نعمل الغيب ففي بداية املشاريع ل نس تطيع تصور النتيجة مئة ابملئة و ل ما قد حيدث خالل التطوير فقط عندما تبدأ بكتابة النص الربجمي ستس توعب املشلكة افضل. احياان يكون التفتيت و البناء عالمة عىل انك تعلمت شيئا جديدا.
خطة تطوير 4.8 فكر بايثون 36 خطة التطوير يه معلية كتابة الربامج. العملية اليت اس تخدمناها يف دراسة احلاةل السابقة يه "الكبسةل و التعممي" خطوات هذه العملية يه: 1. ابدأ بكتابة برانمج صغري بال تعريفات اقرتاانت. 2. مبجرد وقوفه عىل قدميه غلفه )كبسهل( يف اقرتان و اعط الاقرتان اسام. 3. معم هذا الاقرتان ابضافة برمرتات مناسبة. 4. كرر اخلطوات 3-1 اىل ان يصبح دليك مجموعة من الاقرتاانت الفعاةل انسخ و الصق النصوص الربجمية لتكتب اقل و لتقلل عالج الاخطاء. 5. احبث عن الفرص لتحسني الربانمج ابلتفتيت و البناء مفثال ان اكنت هناكل نصوص برجمية متشاهبة يف عدة مواضع قمي الفائدة من تفتيهتا مث بناهئا يف اقرتان أمع. لهذه العملية مساوهئا سرتى بدائل لها لحقا الا اهنا مفيدة ان كنت ل تعمل مس بقا كيف س تقسم برانجمك اىل اقرتاانت فهذه الطريقة س متكنك من التصممي بيامن تكتب الربانمج. مجل التوثيق 4.9 docstring يه حمارف تكتب يف بداية الاقرتان لترشح الواهجة للقاريء documentation( )doc = هاك مثل: def polyline(t, n, length, angle): Draws n line segments with the given length and angle (in degrees) between them T is a turtle for i in range(n): fd(t, length) lt(t, angle) حمارف مجل التوثيق تكون حمصورة بني عالمات اقتباس ثالثية تدعى هذه امجلل أيضا مبحارف متعددة السطور لن الثالثة عالمات اقتباس تسمح بتوزيع انلارف عىل اكرث من سطر. امجلل فهيا تكون موجزة ال أهنا حتتوي عىل معلومات رضورية ملن يريد اس تخدام هذا الاقرتان ترشح ابجياز ما اذلي يفعهل الاقرتان )من دون الغوص يف التفاصيل عن كيف يفعهل( و تبني اثر لك من الربمرتات عىل سلوك الاقرتان و ما هو منط لك برمرت )ان مل يكن بي ن ىا(. كتابة مجل التوثيق هذه جزء همم من تصممي الواهجة فواهجة حسنة التصممي تكون سهةل الرشح و عليه فان كنت تعاين من تفسري اقرتانك يعين أن هناكل جمال للتحسينات عىل الواهجة عىل الارحج. عالج الاخطاء 4.10 الواهجة مثل العقد بني الاقرتان و املنادي هل فاملنادي يوافق عىل دفع برمرتات معينة و الاقرتان يوافق عىل القيام بعمل معني. مفثال عددا حصيحا و ابدلرجات. polyline حيتاج اربعة قرائن: t جيب ان تكون سلحفاة جيب أن تكون عددا موجبا اما n angle length هذه املتطلبات تدعى الرشوط املس بقة preconditions لهنا جيب أن هو عدد القطع املس تقمية و عليه فيجب ان تكون فيجب ان تكون عددا و املفهوم مضنا أنه تتحقق true قبل ان يبدأ الاقرتان ابلتنفيذ.
فكر بايثون 37 املقابل لها هو الرشوط امللحقة و تكون يف هناية الاقرتان تتضمن الرشوط امللحقة التأثري اذلي س يفعهل الاقرتان )كرمس قطع مس تقمية( و أي تأثري جانيب )كتحريك السلحفاة أو اي تغيري يف عاملها.)World( تكون الرشوط املس بقة من مس ئولية املنادي ان خالف املنادي الرشوط )و اليت وث قت بعناية( مث مل يعمل الاقرتان بشلك حصيح فان البق ة عىل عاتق املس تدعي. املعاين 4.11 جتل ية : instance عضو يف مجموعة TurtleWorld يف هذا الفصل اكنت عضو يف مجموعة.TurtleWorld حلقة :loop جزء من النص الربجمي ينف ذ مرارا. الكبسةل :encapsulation معلية حتويل سلسةل من العبارات اىل تعريف اقرتان. التعممي :generalization معلية تبديل الاكئنات اليت ح ددت من دون رضورة )اكلرقام( بيشء عام مناسب )اكملتغريات و الربمرتات(. قرينة لكمة مفتاحية :keyword argument قرينة حتتوي امس الربمرت ك"لكمة مفتاحية". واهجة :interface وصف لكيفية س تعامل الاقرتان مبا فيه اسامء و القرائن و القمي املرجعة و وصفها. التفتيت و البناء :refactoring معلية تعديل برانمج شغال لتحسني واهجات الاقرتاانت و لتحسني اخلصائص الاخرى للنص الربجمي. شلك 4.1: زهور السلحفاة شلك 4.2: فطائر السلحفاة خطة تطوير :development plan معلية كتابة الربامج. مجل التوثيق :docstring حمارف تظهر يف تعريف الاقرتان لتوثيق واهجة الاقرتان. الرشوط املس بقة :precondition متطلبات جيب الايفاء هبا من قبل املنادي قبل ان يبدأ الاقرتان. الرشوط امللحقة :postconditions متطلبات جيب أن يفي هبا الاقرتان قبل ان ينهتيي.
متارين 4.12 مترين : 41 محل النص الربجمي لهذا الفصل من http://thinkpythoncom/code/polygonpy مترين احلل فكر بايثون 38 1. اكتب مجال توثيقية للك من polygon, arc, circle 2. ارمس رسام مس تفا يوحض حاةل الربانمج خالل تنفيذه ل radius( circle(bob, ميكنك القيام ابلعمليات احلسابية يدواي مث اضافة print اىل النص الربجمي. 3. نسخة arc يف القسم 47 ليست دقيقة لن المتثيل اخلطي دلائرة يكون دامئا خارج ادلائرة احلقيقية و لهذا السبب فان السلحفاة تنهتيي بعد املاكن املقصود بعدة مديولاتحلل اذلي مقت به يوحض طريقة للتقليل من هذا اخلطأاقرأ النص الربجمي و انظر ان كنت تس توعبه ان رمست رسام بيانيا قد ميكنك ان ترى كيف يعمل 4.2 اكتب مجموعة اقرتاانت عامة مناسبة حبيث ترمس زهورا كام يف الشلك 4.1 http://thinkpython.com/code/flower.py.http://thinkpython.com/code/polygon.py مترين و يتطلب أيضا 4.3 اكتب مجموعة اقرتاانت عامة مناسبة حبيث ترمس فطائر كام يف الشلك 42 احلل http://thinkpython.com/code/pie.py مترين 4.4 ابلماكن تشكيل حروف الاجبدية الاجنلزيية من مكوانت بس يطة كخطوط مس تقمية و القليل من املنحنيات مصم خطا ميكن رمسه بأقل عدد من املكوانت البس يطة مث اكتب اقرتاان يرمس حروف الاجبدية. س يكون عليك كتابة اقرتان للك حرف و اسامؤها واحضة ك draw_a و.letters.py للمساعدة يف تفحص النص الربجمي ميكنك حتميل turtle typewriter من: draw_b مث ختزن اقرتاانتك يف ملف امسه http://thinkpython.com/code/typewriter.py احلل: و يتطلب أيضا مث اكتب برانجما يرمس http://thinkpython.com/code/letters.py http://thinkpython.com/code/polygon.py مترين 4.5 اقرأ عن اللوالب من.http://en.wikipedia.org/wiki/spiral لولبا ارمخيداي )أو أي لولب اخر(. احلل:.http://thinkpython.com/code/spiral.py
فكر بايثون 39 الفصل اخلامس املرشوطات و الاجرتار مؤثر 5.1 مودولوس احلسايب يعمل مؤثر مودولوس احلسايب عىل الاعداد الصحيحة و يرجع البايق عند قسمة العامل الاول عىل الثاين. ميلث مودولوس يف ابيثون ابشارة النسبة املئوية % و بناؤه نفس بناء الرموز احلسابية الاخرى: مؤثر >>> quotient = 7 / 3 >>> print quotient 2 >>> reminder = 7 % 3 >>> print reminder 1 اذن فناجت قسمة 7 عىل 3 هو 2 و البايق 1. س يظهر لنا ان مؤثر مودولوس مفيد بشلك جعيب فميكنك مثال حفص اذا ما اكن الرمق يقبل القسمة عىل رمق أخر ان اكن انجت س % ص يساوي صفر فان س تقبل القسمة عىل ص. ميكنك ايضا عزل اخر خانة او خاانت من رمق ما. فمحصةل س % 10 س تكون الرمق املوجود يف اخلانة الميىن )يف الاساس 10( و كذكل س % 100 س تكون العددين يف اخر خانتني. تعبريات بوليان 5.2 تعبري بوليان هو تعبري يكون أما حصيحا و اما خطأ true, false ما ييل يه امثةل تس تخدم املؤثر == اذلي يقارن عاملني و يرجع True ان اكان متساويني أو False ان مل يكوان: املؤثر == هو أحد مؤثرات النسبة اما ابيق مؤثراهتا: >>> type(true) <type 'bool'> >>> type(false) <type 'bool'> x!= y x > y x < y x >= y x <= y # # # # # x ال تساوي y x أكبر من y x أصغر من y x أكبر أو تساوي y x أصغر أو تساوي y
فكر بايثون 40 هذه املؤثرات قد تكون مألوفة دليك الا ان مؤثرات ابيثون ختتلف عن املؤثرات احلسابية استعامل اشارة يساوي = مفردة بدل من مزدوجة == خطأ شائع تذكر بأن = يه اشارة تعيني و أن == يه اشارة نس بة فال يوجد يشء ك <= أو <=. املنطقية املؤثرات 5.3 هناكل ثالثة مؤثرات منطقية: and, or, not x > 0 and x < 10 n%2 == 0 or n%3 == 0 عىل 3. أو 2 دلةل هذه املؤثرات )معناها( يشبه معناها يف الاجنلزيية مفثال تكون حصيحة فقط ان اكنت x أكرب من صفر و أخريا الرمز not اذلي يعكس التعبري البولياين فان) y not(x > أن x اصغر من أو تساوي y. و أصغر من 10. تكون حصيحة ان اكن أي من الرشطني حصيحا يعين ان اكن الرمق يقبل القسمة عىل حصيحة ان اكنت x > y ليست حصيحة أي ان أردان ادلقة يف احلديث فأن عوامل املؤثرات املنطقية جيب أن تكون تعبريات بوليان الا ان ابيثون ليس صارما جدا فأي عدد عدا الصفر يفرس بأنه.true >>> 17 and True True ابلماكن الافادة من هذه املرونة الا أن هناك بعض من دقائقها اليت قد تشوش و عليه فالفضل جتنهبا )الا ان كنت تعمل ما تفعل(. 5.4 التنفيذ املرشوط لكتابة برامج مفيدة حنتاج اىل القدرة عىل حفص رشوط ما و منم تعديل سلوك الربانمج بناءا علهيا العبارات الرشطية تعطينا هذه القدرة. ابسط صيغة لهذه العبارات يه: التعبري البولياين بعد يشء. عبارة if x > 0: print 'x is positve' if if يسمى الرشط condition ان حتقق فان العبارة املقصودة ست نفذ و ان مل يتحقق فال حيدث لها نفس بناء تعريف الاقرتان: ترويسة يتبعها منت مبسافات ابدئة. عبارات كهذه تسمى عبارات مركبة. ليس هناك حد لعدد العبارات يف منت if فقط جيب أن حيتوي عىل عبارة واحدة عىل الاقل. احياان يكون من املفيد كون ا نتمل بدون عبارات )عادة مكاكن حمجوز لكتابة نص برجمي مل تس تقر عليه بعد(. ميكنك يف هذه احلاةل اس تخدام عبارة pass اليت ل تفعل يشء: if x < 0: pass #need to handle negative values!
5.5 شلك أخر لعبارة هكذا: التنفيذ البديل if هو التنفيذ البديل حيث تكون هناك اماكنيتان و حت قق فكر بايثون 41 الرشط هو ما يقرر أهيام تنفذ بنا ؤها يكون if x%2 == 0: print 'x is even' else: print 'x is odd' ان اكن ابيق قسمة x عىل 2 صفرا س نعرف بأن x عدد زويج في ظهر لنا الربانمج الرساةل املناس بة اما ان اكنت نتيجة حفص الرشط false أي مل يتحقق فان القسم الثاين من العبارات هو ما سينفذ. مبا أن الرشط ل يتعدى أن يكون true أو false فان بديال واحدا فقط سينفذ تسمى البدائل فروع branches لهنا تفريعات يف رساين التنفيذ. 5.6 املرشوطات املسلسةل أحياان تكون هناك أكرث من اماكنيتني و رضورة وجود أكرث من تفريعتني احدى طرق التعبري عن معليات حوسبة كهذه يه املرشوطات املسلسةل: if x < y: print 'x is less than y' elif x > y: print 'x is greater than y' else: print 'x and y are equal' elif هنا أيضا ست نف ذ تفريعة واحدة فقط. ل يوجد حد لعدد عبارات.else if يه اختصار elif اس تخدام else فيجب وضعها يف الهناية لكن وجود else ليس الرضوري. و ان لزم If choice == 'a': draw_a() elif choice == 'b': draw_b() elif choice == 'c': draw_c() ي فحص لك رشط ابلرتتيب فان اكنت نتيجة حفص الرشط الاول false يفحص الرشط الثاين و هكذا. و ما أن تصادف نتيجة حفص true سينفذ الفرع املعين و تنهتيي العبارة و ان اكن هناك أكرث من رشط true فان أول فرع true فقط سينفذ. 5.7 املرشوطات العش ية قد يتطلب الامر أن تكون احدى املرشوطات حمتضنة )معششة( يف أخرى اكن ابماكننا كتابة الثالثية السابقة اكلتايل: if x == y: print 'x and y are equal' else: if x < y: print 'x is less than y' else: print 'x is greater than y' حتتوي املرشوطة اخلارجية عىل فرعني الفرع الاول حيتوي عىل عبارة بس يطة الثاين حيتوي عىل عبارة if أخرى و اليت
عبارة فكر بايثون 42 بدورها حتتوي عىل فرعني لك من هذين الفرعني عبارة بس يطة هذان الفرعان أيضا ميكن جعلهام عبارات مرشوطة. رمغ أن املسافات البادئة يف هذه الصياغة جتعل قراءة النص سهةل الا أن املرشوطات العشية تصبح برسعة صعبة القراءة فتجنهبا يفضل يف الغالب. املؤثرات املنطقية توفر لنا طريقة لتبس يط املرشوطات العش ية فعىل سبيل املثال ميكننا كتابة النص التايل مرة أخرى ابس تخدام مرشوطة واحدة: if 0 < x: if x < 10: print 'x is a positive single-digit number' print هنا ستنفذ فقط ان جعلناها متر عرب الرشطني ذلا فباماكننا اس تخدام املؤثر and لتحقيق نفس النتيجة: if 0 < x and x < 10: print 'x is a positive single-digit number' الاجرتار 5.8 )العودية( recursion من اجلائز لقرتان نداء اقرتان اخر و من اجلائز ايضا لقرتان أن ينادي نفسه قد ل تكون الفائدة من هذا النداء واحضة الن ال انه س يتبني لنا أن النداء هكذا هو من الامور السحرية اليت يس تطيع الربانمج القيام هبا مفثال انظر اىل الاقرتان التايل: ان اكنت def countdown(n): if n <= 0: print 'Blastoff!' else: countdown(n-1) n n countdown صفرا أو أقل من صفر س ت طبع اللكمة نفسه بمترير 1-n كقرينة. ما اذلي س يحدث عندما ننادي هذا الاقرتان هكذا 'Blastoff!' و ال س ت خرج مث يبدأ تنفيذ countdown ب 3=n و مبا أن n أكرب من 0 س ت خرج القمية 3 مث ينادي الاقرتان نفسه سيبدأ تنفيذ countdown ب 2=n و مبا أن n أكرب من 0 س ت خرج القمية 2 مث ينادي نفسه سيبدأ تنفيذ countdown ب 1=n و مبا أن n أكرب من 0 س ت خرج القمية 1 مث ينادي نفسه سيبدأ تنفيذ countdown ب 0=n و مبا أن n ليست أكرب من 0 س تطبع اللكمة مث يرجع الاقرتان اذلي تلقى = 1 n يرجع الاقرتان اذلي تلقى = 2 n سريجع الاقرتان اذلي تلقى = 3 n سريجع اقرتاان امسه تنادي >>> countdown(3) Blastoff! 3 2 1 Blastoff! و عندها س نعود اىل main فاهلرج اللكي س يكون عىل هذا الشلك:
الاقرتان اذلي ينادي نفسه يدعى اجرتاراي )عوداي( recursive العملية نفسها تسمى و مكثال اخر ميكننا كتابة الاقرتان اذلي يطبع حمارف عدد n من املرات: ان حتققت => 0 n فان عبارة تبقى من سطور الاقرتان لن ينفذ. ابيق الاقرتان يشبه الاضافية تساوي فكر بايثون 43 اجرتارا.recursion Def print_n(s, n): if n <= 0: return print s print_n(s, n-1) return countdown س تخرجنا من الاقرتان و رساين التنفيذ سيعود مبارشة اىل املنادي و ما : ان اكنت n أكرب من صفر فس تطبع فيكون عدد سطور اهلرجات 1 s مث ينادي نفسه ليطبع و جتميعها يكون n. s )n 1( +.n 1 لمثةل بس يطة كهذه من الاسهل اس تخدام حلقة for الا أننا سرنى لحقا أمثةل من الصعب كتابهتا حبلقة الاسهل كتابهتا ابلجرتار لهذا اس تحسنت الابتداء مبكرا. عدد من املرات و for 5.9 الرمس املس تف لالقرتاانت الاجرتارية يف القسم 3.10 اس تعملنا الرمس املس تف لمتثيل حاةل الربانمج عند نداء اقرتان ابماكن نفس نوع الرمس املساعدة يف تفسري الاقرتان الاجرتاري. يف لك مرة يس تدعى فهيا الاقرتان خيلق ابيثون اطار اقرتان جديد حيتوي عىل متغريات الاقرتان املوضعية و برمرتاته يف الاقرتاانت العودية قد يكون هناكل اكرث من اطار يف التستيفة يف نفس الوقت. الشلك 5.1 يبني الرمس املستف ل countdown عند اس تدعاهئا ب = 1 n. اكلعادة أعىل الرمس هو اطار ل main اطارات countdown الاربعة هبا قمي خمتلفة للربمرت عودي ذلكل فال يوجد اطارات اضافية. مترين 5.1 أرمس رسام تستيفيا ل print_n نودي مترين 5.2 اكتب اقرتاان و مسه املرات. و هو فارغ لننا مل نوجد يف main n أية متغريات و مل منرر أية قرائن. أسفل الرمس يسمى حاةل القاعدة base case و ل يقوم بنداء ب' Hello ' s = = 2.n و do_n يأخذ اكئن اقرتان و عدد n كقرائن حبيث يس تدعي الاقرتان املعطى عدد من n شلك 5.1 الرمس املستف
منهتيي الال الاجرتار 5.10 فكر بايثون 44 ان مل يصل الاجرتار اىل احلاةل الساس فس يقوم بنداءات اجرتارية اىل الابد و لن يتوقف تنفيذ الربانمج. يعرف هذا ابلجرتار الال منهتيي و هو يف العموم ليس ابلمر اجليد هاك برانمج صغري و اجرتار ل منهتيي: def recurse(): recurse() أغلب بيئات الربجمة ل تسمح لربامج هبا اجرتار ل منهتيي من التنفيذ اىل الابد و ابيثون يصدر رساةل وجود خطأ ان جتاوز عدد النداءات العمق الاقىص: File <stdin>, line 2, in recurse File <stdin>, line 2, in recurse File <stdin>, line 2, in recurse... File <stdin>, line 2, in recurse RuntimeError: Maximum recursions depth exceeded هذه املالحقة اكنت أكرب قليال مما شاهدان يف الفصل السابق فعند ورود اخلطأ يكون عدد الاجرتارات قد وصل اىل ألف يف التستيفة! 5.11 مدخالت لوحة املفاتيح اكنت الربامج اليت كتبناها حىت الان فظة من حيث أهنا ل تقبل مدخالت من املس تخدم فهيي تفعل نفس اليشء لك مرة و حسب. ابيثون 2 يوفر اقرتاان جاهزا امسه raw_input يقبل املدخالت من لوحة املفاتيح أما يف ابيثون 3 فامسه عند نداء هذا الاقرتان يتوقف الربانمج و ينتظر بأن يقوم املس تخدم بطباعة يشء ما و عند ضغط املس تخدم زر أو Return فان الربانمج يتابع و يرجع الاقرتان raw_input ما طبعه املس تخدم من املس تحسن قبل أخذ امل دخل من املس تخدم أن نطبع شيئا يقول للمس تخدم ماذا يدخل. هنا أخذ حمث كقرينة:.input Enter >>> text = raw_input() What are you waiting for? >>> print text What are you waiting for? raw_input تس تطيع >>> name = raw_input('what...is your name?\n') What is your name? Atrhur, King of the Britons! >>> print name Arthur, King of the Britons! التسلسل n\ يف هناية انلث يعين سطرا جديدا و هو حرف خاص يسبب قطع يف السطر و لهذا يظهر م دخل املس تخدم يف السطر اذلي ييل انلث. ان كنت تتوقع من املس تخدم ان يدخل عددا حصيحا فميكنك حماوةل حتويل القمية املرجعة اىل :int >>> prompt = 'What...is the airspeed velocity of an unladen swallow?\n' >>> speed = raw_input(prompt) What...is the airspeed velocity of an unladen swallow? 17
فكر بايثون 45 اما ان طبع املس تخدم ما هو غري حمارف من اخلاانت العددية فس تحصل عىل خطأ: >>> int(speed) 17 >>> speed = raw_input(prompt) What...is the airspeed velocity of an unladen swallow? What do you mean, an African or a European Swallow? >>> int(speed) ValueError invalid literal for int() with base 10 5.12 عالج الاخطاء املالحقة اليت يظهرها ابيثون عند حدوث اخلطأ حت وي من املعلومات الكثري الا أهنا قد تكون مفرطة أيضا خصوصا ان اكنت هناك اطر عديدة يف التستيفة أكرث اجزاء املالحقة افادة يه: ما هو نوع اخلطأ و أين وقع. هناك بضعة مأخذ عىل قويل سابقا بأن الخطاء الكتابية سهةل الاكتشاف يف العادة. فأخطاء الفراغات قد تصبح خمادعة لن الفراغات و املسافات البادئة ل ت رى و حنن تعودان عىل جتاهلها: >>> x = 5 >>> y = 6 File <stdin>, line 1 y = 6 IndentationError: unexpected indent اكنت املشلكة يف هذا املثال أن السطر الثاين أبعد بفراغ واحد الا أن رساةل وجود اخلطأ تشري اىل y مما قد ميوه احلقيقة بشلك عام تؤرش رسائل وجود الخطاء املاكن اذلي لوحظ فيه وجود خطأ الا أن اخلطأ احلقيقي قد يكون يف سطر أبكر من سطور النص أحياان يف السطر السابق يطبق ما س بق أيضا عىل الخطاءاليت تظهر عند التشغيل لنفرض أنك تريد حوس بة نس بة الاشارة التشويش ابدلس بل املعادةل يه ) noise.snr db = 10log 10 P) signal P/ ميكنك يف ابيثون كتابة يشء كهذا: الا انك عند تشغيل الربانمج يف ابيثون 2 س تحصل عىل خطأ. import math signal_power = 9 noise_power = 10 ratio = signal_power / noise_power decibels = 10 * math.log10(ratio) print decibels Traceback (most recent call last): File snrpy, line 5, in? Decibels = 10 * math.log10(ratio) ValueError: math domain error تشري الرساةل اىل وجود خطأ يف السطر اخلامس لكننا نرى بأن السطر عىل ما يرام ليك نكتشف اخلطأ احلقيقي قد يفيدان طباعة قمية ratio و سيتضح لنا بأهنا 0 فاملشلكة اذن يف السطر الرابع لن تقسمي عددين حصيحني اكن قسمة أرضية
احلل هنا هو متثيل قمي signal_power و اكتشاف اخلطأ و هو ليس املاكن اذلي سبب اخلطأ ابلرضورة. فكر بايثون 46 noise_power بقمي عامئة اذن فرساةل وجود اخلطأ ستبلغك مباكن لن حتصل عىل هذا اخلطأ يف ابيثون 3 لن رمز القسمة هناك يقوم بقسمة نقاط عامئة و ان اكنت العوامل أعداد حصيحة. 5.13 تعبري مؤثر مؤثر املعاين مؤثر موديولس :modulus operator من املؤثرات احلسابية متثهل اشارة % عوامهل أعداد حصيحة و انجت العملية يكون ابيق قسمة العامل عىل الاخر. بوليان : Boolean expression تعبري تكون قميته اما True أو.False نس بة منطقي :relational operator أحد مؤثرات املقارنة بني العوامل:,==!=,,> <, <= و.>=.and, or, not أحد املؤثرات اليت جتمع تعبريات بوليان: :logical operator عبارة مرشوطة :conditional statement عبارة تتحمك يف رساين التنفيذ بناءا عىل رشط ما. رشط :condition تعبري بوليان يف عبارة مرشوطة حيدد أي من الفروع سيمت تنفيذه. عبارة مركبة :compound statement عبارة تتألف من ترويسة و منت تنهتيي الرتويسة ب : و سطور املنت لها مسافات ابدئة ابلنس بة للرتويسة. فرع :branch أحد تسلسالت العبارات البديةل يف العبارة املرشوطة. املرشوطات املسلسةل املرشوطات العش ية chained :عبارة conditional مرشوطة هبا سلسةل من الفروع البديةل :nested conditional عبارة مرشوطة تظهر يف أحد فروع عبارة مرشوطة أخرى. الاجرتار :recursion معلية نداء الاقرتان اذلي ينفذ حاليا و يسمى أحياان ابلعودية. احلاةل الاوىل الال الاجرتار :base case فرع مرشوط يف اقرتان اجرتاري ل يقوم بنداء اجرتاري. منهتيي :infinite recursion الاجرتار اذلي ليس هل حاةل أساس. 5.14 مترين متارين 5.3 تقول نظرية فرمات الاخرية بأنه ل توجد أعداد موجبة حصيحة a و b و c حبيث أن لي قمية ل n أكرب من 2. a n + b n = c n.1 اكتب اقرتاان امسه check_fermat يأخذ أربعة برمرتات نظرية فرمات س تصمد أم ل فان اكنت n أكرب من 2 و اكن حق ىا أ ن a, b, c, n a n + b n = c n مث يفحص اذا ما اكنت فعىل الربانمج طباعة wrong Holy smokes, Fermat was و ال فعىل الربانمج طباعة. No, that doesn't work
.2 فكر بايثون 47 أكتب اقرتاان يطلب من مس تخدمه ادخال قمي ل,a,b c و n مث حيولها لعداد حصيحة و بعدها يس تخدم check_fermat ليفحص اذا ما اكنت ختالف نظرية فرمات. مترين 5.4 ان أأعطيت ثالثة عيص فقد تس تطيع أو قد ل تس تطيع تكوين مثلث مهنا مفثال ان اكن طول احداها 12 انشا و طول لك من الاخريني انشا واحدا يكون جليا أهنا لن تك ون مثلثا فلن تس تطيع جعل العصاتني القصريتني تلتقيان يف الوسط. لكن لي ثالثة أطوال هناكل طريقة سهةل ملعرفة ان اكنت س تك ون مثلثا أم ل: ان اكن طول أي من الضالع أكرب من مجموع طويل الضلعني الخريني لن تمتكن من تشكيل مثلث و العكس حصيح )ان اكن مجموع طويل الضلعني يساوي الضلع الثالث فاهنا تشلك ما امسه مثلثا متفسخا!(. 1. اكتب اقرتاان امسه is_triangle يأخذ ثالثة أعداد حصيحة كقرائن و يطبع Yes أو No حسب اماكنية تكوين املثلث من الطوال املعطاة. 2. أكتب اقرتاان يطلب من املس تخدم ادخال ثالثة أطوال للعيص و حيولها لعداد حصيحة مث يس تخدم is_triangle لفحص ما اذا اكنت تكون مثلثا الامترين التالية تس تخدم TurtleWorld من الفصل الرابع: مترين 5.5 أقرأ الاقرتان التايل و حا ول معرفة ما اذلي يقوم به مث شغهل )أنظر الامثةل يف الفصل الرابع( المترين الشلك 5.2 منحىن كوخ def draw(t, length, n): if n == 0: return angle = 50 fd(t, length*n) lt(t, angle) draw(t, length, n-1) rt(t, 2*angle) draw(t, length, n-1) lt(t, angle) bk(t, length*n) 5.6 منحىن كوخ هو كسريية fractal اكلشلك 5.2 ليك ترمس منحىن كهذا لك ما عليك فعهل هو: 1. أرمس منحىن كوخ بطول 3/x. 2. در يسارا 60 درجة. 3. ارمس منحىن كوخ بطول 3/x. 4. در يسارا 120 درجة. 5. ارمس منحىن كوخ بطول 3/x. 6. در يسارا 60 درجة. 7. أرمس منحىن كوخ بطول 3/x.
الاس تثناء هو ان اكنت x فكر بايثون 48 أقل من 3: يف هذه احلاةل ارمس خطا مس تقامي بطول x فقط. 1- اكتب اقرتاان و مسه koch يأخذ السلحفاة و الطول كربمرتات مث يس تخدم السلحفاة لرمس منحىن كوخ ابلطول املعطى. 2- اكتب اقرتاان و مسه snowflake لريمس منحىن كوخ يكون شلكه الهنايئ كبلورة ثلج. احلل:.http://thinkpython.com/code/koch.py 3- ميكن تعممي منحىن كوخ بعدة طرق أنظر http://en.wikipedia.org/wiki/koch_snowflake و اخرت املثال اذلي تفضهل.
فكر بايثون 49 الفصل السادس الاقرتاانت املمثرة القمية املرجعة 6.1 return value بعض الاقرتاانت اجلاهزة اليت اس تعملناها اكلقرتاانت الرايضية لها نتاجئ. نداء الاقرتان يودل قمية نعيهنا العادة ملتغري أو نضعها يف تعبري. A = mathexp(1.0) height = radius * math.sin(radians) مجيع الاقرتاانت اليت كتبناها حىت الان اكنت عقمية قد تطبع شيئا أو حترك السلحفاة الا أن القمية اليت ترجعها اكنت دامئا.None يف هذا الفصل س نكتب )أخريا( اقرتاانت ممثرة. املثال الاول س يكون area و اذلي سريجع مساحة دائرة لها نصف قطر معطى. Def area(radius): temp = math.pi * radius**2 return temp return لقد مرت علينا عبارة return من قبل لكن يف الاقرتاانت املمثرة فان عبارة حتتوي عىل تعبري. هنا هذه العبارة تعين " ارجع فورا من هذا الاقرتان و اس تخدم التعبري التايل كقمية مرجعة". ميكن للتعبري أن يصبح ابلغ التعقيد و من أجل الجياز لكنا قد كتبنا هذا الاقرتان هكذا: لكن من الناحية الخرى فان املتغريات املؤقتة def area(radius): return math.pi * radius**2 مثل temp تسهل اكتشاف من املفيد أحياان ادراج عدة عبارات ارجاع واحدة يف لك فرع يف مرشوطة: الخطاء. def absolute)value(x): if x < 0: return -x else: return x فامب أن عبارات الارجاع هذه موضوعة يف مرشوطة بدائلية فان واحدة مهنا فقط ستنفذ. مبجرد تنفيذ عبارة الارجاع فان الاقرتان سيتوقف بدون تنفيذ أي من العبارات اليت تيل عبارة الارجاع النص اذلي يظهر بعد return أو يف أي موضع ل يصهل رساين التنفيذ يسمى نصا برجميا ميتا. يف الاقرتاانت املمثرة من اجليد أن تتأكد من أن أي مسار برجمي يف الربانمج املطلقة:.return س يصطدم بعبارة ارجاع مثال اقرتان القمية def absolute_value(x):
فكر بايثون 50 if x < 0: return -x if x > 0: return x هنا هذا الاقرتان غري حصيح لنه ان اكنت x صفرا فلن يتحقق أي من الرشطني و س ينهتيي الاقرتان من دون أن يصادف return و اذا وصل رساين التنفيذ اىل هناية الاقرتان س تكون قمية الارجاع None و يه ليست القمية املطلقة ل 0. ابملناس بة ابيثون يوفر اقرتاان جاهزا يدعى abs حيسب القمية املطلقة. >>> print absolute_value(0) None مترين 6.1 اكتب اقرتان امسه compare اكنت.x < y عندما تكون 1 يرجع و صفر ان اكنت x == y مث -1 x > y ان 6.2 التطوير العصايم بيامن تتضخم الاقرتاانت اليت تطورها س تجد نفسك تنفق املزيد من الوقت يف عالج الاخطاء. لتمتكن من التعامل مع الربامج اليت تتعقد ابضطراد قد تس تفيد من معلية تدعى التطوير العصايم incremental development الهدف هو جتنب جلسات عالج الخطاء الطويةل عن طريق اضافة نصوص برجمية صغرية مرة بعد مرة. مكثال افرتض أنك تريد اجياد املسافة بني نقطتني املعطيات يه احداثيات النقطتني ( 1 x( 1 y, و ( 2 x( 2 y, فيثاغوروس تقول بأن املسافة يه: نظرية ) 2 1 (x 2 x 1 ) 2 + (y 2 y = المسافة اخلطوة الاوىل أن تضع تصورا ملا سيبدو عليه اقرتان distance يف ابيثون أي ما يه املعطيات )الربمرتات( و ما يه النتاجئ )القمية املرجعة return ( يف حالتنا هذه اكنت املعطيات نقطتان و ت مث ل يف أربعة أرقام و القمية املرجعة اكنت املسافة و اليت ت مث ل يف قمية حقيقية.floating-point أنت الان جاهز لكتابة اخلطوط العريضة لالقرتان: def distance(x1, y1, x2, y2): return 0.0 من الواحض أن هذه النسخة من برانجمك لن حتسب لنا املسافة فالق مية املرجعة س تكون دامئا صفر الا أهنا صيغة حنوية حصيحة و تعمل اذلي يعين أنه ميكنك اختبارها الن و قبل أن يزداد تعقيدها. لفحص الاقرتان اجلديد اس تدعها بقرينة بس يط: >>> distance(1, 2,4,6) 0.0 اخرتت هذه القمي حبيث تكون املسافة الافقية 3 و العمودية 4 و هكذا س تكون النتيجة 5 )وتر املثلث 5-4-3( من الفيد معرفة النتيجة مس بقا عند حفص الاقرتاانت. يف هذه املرحةل تأكدان من أن بناء الاقرتان حصيح ابماكننا الان اضافة النصوص الربجمية ملنت الاقرتان. منطقيا اخلطوة التالية س تكون اجياد الفرق x 2 - x 1 و كذكل 2 y - 1 y اذن فالنسخة التالية من الاقرتان س تخزن هذه القمي يف متغريات مؤقتة و س تطبعها:
فكر بايثون 51 def distance(x1, y1, x2, y2): dx = x2 x1 dy = y2 y1 print 'dx is', dx print 'dy is', dy return 0.0.'dy is 4' 'dx is 3' ان حدث هذا ان معل الاقرتان بعد هذه الاضافة فيجب أن يظهر عىل الشاشة و فس نعمل بأن الاقرتان أخذ القرائن الصحيحة و قام ابحلوس بة الاوىل بشلك حصيح و ال فلك ما بني يدينا هو فقط بضعة سطور لعالج اخطاهئا. التايل هو حساب مجع مربعات def distance(x1, y1, x2, y2): dx = x2 x1 dy = y2 y1 print 'dx is', dx print 'dy is', dy dsquared = dx**2 + dy**2 return 0.0 : dy و dx مرة أخرى شغل الربانمج و تأكد من اهلرجات )تعمل مس بقا أهنا 25(. و أخريا ستسخدم math.sqrt لرجاع النتيجة: def distance(x1, y1, x2, y2): dx = x2 x1 dy = y2 y1 print 'dx is', dx print 'dy is', dy dsquared = dx**2 + dy**2 result = maths.qrt(dsquared) return result ان اكنت النتيجة حصيحة فقد انهتيت من كتابة برانجمك و ان مل تكن فقد يتطلب الامر طباعة قمية result قبل عبارة.return ل ت ظهر النسخة الاخرية من الاقرتان أي يشء عند تشغيلها ترجع قمية فقط. عبارات print اليت كتبناها مفيدة يف عالج الاخطاء ذلكل فمبجرد الانهتاء من النص و التأكد من خلوه من الخطاء فالفضل ازالهتا. نص كهذا يدعى السق الت scuffolding لنه يساعد يف بناء الربانمج لكنه ليس البناء حبد ذاته. عند البدء بكتابة برانمج عليك أن تضيف سطر أو اثنان يف لك مرة و لكام زادت خربتك س تجد أنه ابماكنك كتابة و عالج أخطاء نصوص أكرب و أاي اكنت احلال فان التطوير العصايم يقلل كثريا من وقت عالج الاخطاء. العنارص الرئيس ية يف هذه العملية يه: 1. ابدأ بربانمج يعمل مق بتعديالت صغرية وعند وجود خطأ يف أي مرحةل س تكون دليك فكرة واحضة عن موضعه. 2. اس تخدم املتغريات املؤقتة و عني لها القمي اليت تريد حفصها. 3. عندما تشعر ابلرىض عن معل الربانمج تس تطيع حذف بعضا من السق الت. و تس تطيع دمج عدة عبارات يف تعبري مركب هذا فقط ان اكن ادلمج ل يصع ب قراءة الربانمج. مترين 6.2 اس تخدم التطوير العصايم لكتابة اقرتان و مسه أعطي طويل الضلعني الاخريني. جسل لك خطوة يف العملية. hypotenuse حبيث يرجع طول وتر مثلث قامئ الزاوية ان
الرتكيب 6.3 فكر بايثون 52 كام توقعت فانه ميكنك نداء اقرتان من داخل اخر. هذه الماكنية تدعى الرتكيب )أو التوليف.)composition مكثال لها س نكتب اقرتان يأخذ نقطتني احداها مركز دائرة و الاخرى نقطة عىل حميطها مث س يحسب مساحة ادلائرة. لنفرض أننا عينا احداثيات املركز للمتغريين xc و yc و احداثيات نقطة انليط xp و yp )انليط = )perimeter س تكون اخلطوة الاوىل اجياد نصف قطر ادلائرة و هو مسافة بني نقطتني و مبا أننا كنا قد كتبنا منذ حلظات اقرتان جيد هذه املسافة و مسيناه :distance radius = distance(xc, yc, xp, yp) اذن س ننتقل مبارشة اىل اخلط وة التالية و يه حساب مساحة ادلائرة لكننا كتبنا هذا الاقرتان من قبل أيضا: كبسةل هاتني اخلطوتني يف اقرتان س تنتج لنا: املتغريات املؤقتة radius و ميكننا الاجياز بدمج عبارات النداء: result = area(radius) def circle_area(xc, yc, xp, yp): radius = distance(xc, yc, xp, yp) result = area(radius) return result result مفيدة يف التطوير و يف عالج الاخطاء لكن مبجرد معل الربانمج بشلك حصيح def circle_area(xc, yc, xp, yp): return area(disance(xc, yc, xp, yp)) اقرتاانت بوليان 6.4 تس تطيع الاقرتاانت ارجاع بوليان False) (True, و يه وسيةل جيدة لخفاء الفحوص املعقدة داخل الاقرتان مثال: من الشائع اعطاء اقرتاانت بولني أسامء كس ئةل جتاب بنعم أو ل y. تقبل القسمة عىل x للتبيني ان اكنت )False( أو خطأ )True( هاك مثال: نتيجة معلية املؤثر == يه بوليان ذلا ميكننا اجياز الاقرتان ابرجاع النتيجة مبارشة: اقرتاانت بوليان تس تخدم كثريا يف العبارات املرشوطة: قد يغرينا هذا الامر بكتابة يشء كهذا: def is_divisable(x, y): if x % y == 0: return True else: return Fals is_divisable )هل يقبل القسمة( س تعيد اما حص >>> is_divisable(6, 4) False >>> is_divisable(6, 3) True def is_divisable(x, y): return x % y == 0 if is_divisabel(x, y): print 'x is divisable by y'
فكر بايثون 53 الا أن املقارنة الثانية اكنت زائدة و غري رضورية. مترين if is_divisable(x, y) == True: print 'x is divisable by y' 6.3 اكتب الاقرتان( z in_between(x,,y اذلي يرجع True.False ان اكنت x y z و ال سريجع 6.5 املزيد من الاجرتار لقد غطينا جزءا يسريا من ابيثون فقط الا أنك س تعجب ان علمت بأن هذا اجلزء هو لغة برجمة اكمةل مما يعين أن أي يشء ميكن حوسبته ميكن التعبري عنه هبذه اللغة. أي برانمج اس تخدمته ميكنك كتابة مثيل هل ابس تخدام املزااي اليت تعلمهتا حىت الان فقط )لدلقة س تحتاج لبضعة أوامر للتحمك بأدوات لكوحة املفاتيح الفأرة الاقراص ال أن هذا لك ما هناكل(. للربهان عىل حصة هذا الادعاء هناكل مترين غري عادي مصمه لول مرة واحد من أوائل علامء احلاسوب ألن تورنغ البعض حياجج بأنه اكن رايضيا الا أن كثري من علامء احلاسوب الاوائل اكنوا رايضيني( مسي هذا المترين أطروحة تورنغ. لالطالع عىل نقاش الاطروحة بشلك موسع ( و دقيق( أويص بكتاب ميش يل سبرس "مدخل اىل نظرية احلوسبة". ليك تأخذ فكرة عام ميكنك معهل ابلدوات اليت تعلمت اس تخداهما حىت الان س نقوم بتقيمي بضعة اقرتاانت رايضية اجرتارية التعريف. التعريف الاجرتاري لقرتان يش به التعريف التدويري من منطلق أن التعريف يتضمن اشارات للمعر ف التعريف التدويري حبد ذاته عدمي الفائدة يف العموم: فورابل: يه صفة ملا هو فورابل. ان رأيت ما س بق يف معجم س تزنجع كهذا: يف املقابل ان حبثت عن تعريف اقرتان املرضوب و اذلي يرمز هل ب! س تجد شيئا 0! = 1 n! = n(n 1)! يقول لنا هذا التعريف بأن مرضوب 0 هو 1 و مرضوب أي قمية أخرى n هو nمرضواب مبرضوب 1-n جس نا مفرضوب 3 هو 3 رضب 2! و اذلي هو 2 رضب 1! و اذلي هو 1 رضب 0! عندما تقوم بلك العمليات احلسابية فان 3 يه! 3 رضب 2 رضب 1 رضب 1 و ابلتايل 6. ان اكن ابس تطاعتك كتابة تعريف اجرتاري ليشء ما فعىل الاغلب س يكون بوسعك كتابة برانمج ابيثون يقي مه. اخلطوة الاوىل يه أن تقرر ماذا س تكون الربمرتات يف حالتنا هذه جيب أن يكون واحضا لنا بأن factorial تأخذ أعدادا حصيحة: و ان اكن هذا العدد الصحيح صفرا فعىل الاقرتان أن يرجع 1: و ال و هذا هو اجلزء املهم علينا القيام بنداء اجرتاري لجياد مرضوب 1-n مث نرضبه ب n: def factorial(n): def factorial(n): if n == 0: return 1 def factorial(n):
فكر بايثون 54 if n == 0: return 1 else: recurse = factorial(n-1) result = n * recurse return result رساين التنفيذ يف هذا الربانمج يشبه ذكل يف countdown يف القسم 5.8 فان اس تدعينا factorial ابلقمية : 3 مبا أن 3 ليست صفرا سمنر يف الفرع الثاين و حنسب قمية مرضوب n-1 مبا أن 2 ليست صفرا سمنر يف الفرع الثاين و حنسب قمية مرضوب 1-n و مبا أن 1 ليست صفرا سمنر يف الفرع الثاين و جنسب قمية مرضوب 1-n مبا أن 0 يه 0 س نأخذ الفرع الاول و نعيد 1 دون القيام بنداءات اجرتارية أخرى س ترضب القمية املرجعة )1( ب n و يه 1 و سرتجع النتيجة النتيجة املرجتعة 1 س ترضب ب n و يه 2 و سرتجع النتيجة القمية املرجتعة 2 س ترضب ب n و يه 3 و النتيجة 6 س تصبح القمية اليت سريجعها نداء الاقرتان اذلي بدأ هذه العملية. الشلك 6.1 يبني الرمس املستف لهذا التسلسل يف نداء اقرتان تظهر القمي املرجعة و يه مترر عائدة اىل الاعىل يف التستيفة ففي لك اطار تكون القمية املرجعة يه قمية يه حاصل رضب n يف.recurse يف الاطار الاخري ختتفي املتغريات املوضعية لن الفرع اذلي أوجدها مل ينفذ. return و اليت الشلك 6.1 رمس مستف وثبة ثقة 6.6 تتبع رساين التنفيذ هو احدى طرق قراءة الربامج الا أنه رسعان ما يصبح الربانمج مكتاهة. البديل لهذه الطريقة يه ما يسمى قفزة الثقة. عندما تصل اىل عبارة نداء اقرتان بدل من اتباع رساين التنفيذ اف رتض بأن الاقرتان يعمل بشلك حصيح و يرجع النتيجة الصحيحة. هذا ليس جبديد فأنت تقوم بقفزات الثقة هذه عندما تس تخدم الاقرتاانت اجلاهزة عندما تس تدعي math.cos أو
math.exp عتاة. فكر بايثون 55 فأنت ل تتفحص منت هذه الاقرتاانت تفرتض فقط بأهنا حصيحة لن من كتب هذه الاقرتاانت مربجمون ينطبق نفس اليشء عندما تكتب أقرتانك. مفثال يف القسم 6.4 كتبنا اقرتاان امسه is_divisible يقرر اذا ما اكن عدد ما يقبل القسمة عىل اخر و مبجرد أن أقنعنا أنفس نا بأن الاقرتان أصبح حصيحا بعد حفص النص و جتربة الاقرتان أمكننا اس تخدام الاقرتان دون النظر يف متنه اثنية. نفس اليشء حصيح ابلنسبة للربامج الاجرتارية فعندما تصل اىل عبارة نداء اجرتارية بدل من اتباع رساين التنفيذ عليك افرتاض حصة معل النداء الاجرتاري )و أنه يصدر النتيجة الصحيحة( مث تسأل نفسك "لو اكن ابماكين اجياد مرضوب 1-n هل بوسعي حساب مرضوب n " يف هذه احلاةل واحض أنه ميكنك عن طريق الرضب يف n. طبعا قد يكون افرتاض أن الاقرتان يعمل غريبا بعض اليشء عندما مل تنته من كتابته بعد الا أن هذا هو سبب تسمية الطريقة ب قفزة ثقة. أخر مثال 6.7 يف العادة بعد املرضوب مكثال لرشح الاجرتار يأيت فبوانيش و هل هذا التعريف أنظر : (http://en.wikipedia.org/wiki/fibonacci_number( def fibonacci (n): if n == 0: return 0 elif n == 1: return 1 else: return fibonacci(n-1) + fibonacci(n-2) فبوانيش) 0 ( = 0 فبوانيش) 1 ( = 1 فبوانيش) n ( = فبوانيش) 1 - )n + فبوانيش) 2 - )n عند كتابته يف ابيثون سيبدو هكذا: ان حاولت تتبع رساين التنفيذ هنا حيت لقمية صغرية ل n سينفجر دماغك لكن حسب قفزة الثقة ان افرتضت بأن النداءين الاجرتارين يعمالن بشلك حصيح س يكون من الواحض ان النتيجة الصحيحة س تأيت عند مجعهام معا. 6.8 حفص الامناط ما اذلي س يحدث عندما نس تدعي factorial و منرر هل 1.5 كقرينة >>> factorial(1.5) RuntimeError: Maximum recursion depth exceeded يبدو اكجرتار ل هنايئ و لكن هل ميكن هذا فهناك حاةل أساس ويه عندما تكون == 0 n. لكن ما حيدث هو أنه عندما ل تكون n عددا حصيحا فقد ل نصادف حاةل الاصل و جنرت اىل الابد. يف النداء الاجرتاري الاول اكنت قمية n تساوي 0.5 و يف النداء اذلي تاله اكنت 0.5- و بعدها ستسمتر القمية يف النقصان
)سالبا( الا أهنا لن تصل اىل الصفر. فكر بايثون 56 هنا يصبح دلينا خيارين اما تعممي factorial لتعمل عىل الاعداد احلقيقية أو جعل factorial يفحص منط القرينة. اخليار الاول يدعى اقرتان جاما و هو أبعد قليال عن الفكرة من هذا الكتاب ذلكل س نأخذ اخليار الثاين. بوسعنا اس تخدام اقرتان جاهز يسمى قمية القرينة موجبة: isinstance للتأكد من منط القرينة و بيامن نفعل ذكل بوسعنا أيضا التأكد من أن def factorial (n): if not isinstance(n, int): print 'Factorial is only defined for integers' return None elif n < 0: print 'Factorial is not defined for negative integers' return None elif n == 0: return 1 else: return n * factorial(n-1) حاةل الساس الاوىل تتعامل مع الاعداد غري الصحيحة و الثانية تلتقط الاعداد السالبة يف لكتا احلالتني س يطبع الربانمج رساةل وجود خطأ و يرجع قمية None لالعالن بأن شيئا ما اكن خطأ: و ان متكنا من عبور الفحصني س نعرف بأن >>> factorial('fred') Factorial is only defined for integers None >>> factorial(-2) Factorial is not defined for negative integers None n اما موجبة أو صفر اذن فباماكننا اثبات أن الاقرتان سيهنيي معهل ميثل هذا الربانمج منطا يسمى أحياان الويص gardian فاملرشوطتني الاوليني تعمالن كويص حتميان النص من قمي قد تسبب خطأ الويص ميك ننا من التأكد من حصة النص الربجمي. يف القسم 11.3 سرنى بدائل أكرث مرونة لطباعة رسائل وجود اخلطأ: رفع اس تثناء. عالج الاخطاء 6.9 تقسمي نص برجمي طويل اىل أجزاء خيلق حماسمي طبيعية تفيد يف عالج احامتلت: هناك خطأ يف القرائن ايتل مررت لالقرتان خمالفة لحد الرشوط املس بقة. هناك خطأ يف الاقرتان خمالفة لحد الرشوط امللحقة. خطأ يف القمية املرجعة أو يف طريقة اس تعاملها. ليك تس تثين الاحامتل الاول ميكنك اضافة ميكنك كتابة نص خمصص لفحص الرشوط املس بقة ان اكنت الربمرتات عىل ما يرام اضف print print الخطاء. ان اكن الاقرتان ل يعمل فهناك ثالثة يف بداية الاقرتان لتطبع قمي الربمرتات ( و رمبا أمناطها( أو حىت أنه قبل لك عبارة return تطبع قمية الارجاع و ان أمكنك فتأكد من
النتيجة يدواي فكر بايثون 57 قد يكون من املفيد نداء الاقرتان بقمي سهةل ليتسىن حفص النتاجئ برسعة )كام يف القسم 6.2( ان بدا أن الاقرتان يعمل بشلك حصيح فانظر يف نداء الاقرتان و تأكد من أن القمية املرجعة تس تعمل بشلك حصيح )أو ان اكنت تسعمل أصال(. اضافة عبارة يف بداية و هناية الاقرتان يساعد يف جعل رساين التنفيذ مرئيا مفثال هنا نسخة من هبا عبارات :print def factorial(n): space = ' ' * (4 * n) print space, 'factorial', n if n == 0: print space, 'returning 1' return 1 else: recurse = factorial(n-1) result = n * recurse print space, 'returning', result return result print factorial هنا space يه حمارف من الفراغات تتحمك ابملسافات البادئة للمخرجات. ها يه نتيجة( factorial(5 : factorial 5 factorial 4 factorial 3 factorial 2 factorial 1 factorial 0 returning 1 returning 1 returning 2 returning 6 returning 24 returning 120 هذه النتيجة توحض معىن رساين النتفيذ و ميكن هلرج كهذا أن يكون مفيدا تركيب سقالت فعاةل قد يأخذ بعض الوقت الا أنه س يوفر وقتا أطول عند عالج الاخطاء 6.10 متغري مؤقت املعاين :temporary variable متغري يس تخدم لالحتفاظ ابلقمي مؤقتا يف معلية حسابية معقدة. نص ميت :dead code جزء من الربانمج لن ينفذ أبدا غالبا لنه يظهر بعد عبارة.return :None قمية خاصة يرجعها اقرتان ليس به عبارة return أو أن عبارة الارجاع بدون قرائن. التطوير العصايم :incremental development خطة تطوير برانمج هدفها التقليل من عالج أخطائه عن طريق اضافة و حفص القليل من النص الربجمي يف لك مرة. السقالت :scuffolding نص برجمي يس تخدم خالل تطوير الربانمج لكنه ليس جزءا من املنتج الهنايئ. الويص :Guardian منط برجمي يس تعمل العبارات املرشوطة للفحص و التعامل مع الظروف اليت قد تودل خطأ.
متارين فكر بايثون 58 def b(z): prod = a(z, z) print z, prod return prod def a(x, y): x = x + 1 return x * y def c(x, y, z): total = x + y + z square = b(total)**2 return square x = 1 y = x + 1 print c(x, y+3, x+y) 6.4 ارمس رسام مس تفا للربانمج التايل ما اذلي س يطبعه الربانمج 6.11 مترين احلل:.http://thinkpython.com/code/stack_diagram.py مترين 6.5 اقرتان أكرمان (n A(m, يعرف اكلتايل: { n = 1 if m = 0 A)m, n( = A)m 1,1( if m > 0 and n = 0 A)m 1,A)m, n-1(( if m > 0 and n > 0.http://en.wikipedia.org/wiki/Ackermann_function ack(3, 4) أنظر اكتب اقرتاان و مسه ack تقمي به اقرتان أكرمان اس تخدم اقرتانك لتقيمي ماذا س يحدث عند تعيني قمي أكرب ل m و n و اذلي جيب أن يكون 125. احلل:.http://thinkpython.com/code/ackermann.py مترين 6.6 اللكامت املتناظرة palendromes يه لكامت تقرأ من اليسار اىل الميني كام تقرأ من الميني اىل اليسار مثل سوس و سلس و noon و.redivider اجرتاراي تكون اللكمة متناظرة ان اكن أولها و اخرها نفس احلرف مث اكن ما تبقى لكمة متناظرة. def first(word): return word[0] def last(word): return word[-1] الاقرتان التايل يأخذ حمارف كقرينة و يرجع احلرفني الاول و الاخري و حروف الوسط:
فكر بايثون 59 سرنى طريقة معل هذه التعريفات يف الفصل الثامن. def middle(word): return word[1:-1] 1. اطبع هذه الاقرتاانت الثالث يف يف ملف و مسه palindrome.py مث تفحص معلها ما اذلي س يحدث ان اس تدعيت middle بسلسةل من حرفني حرف واحد و ماذا عن حمارف فارغة و اليت تكتب هكذا '' 2. اكتب اقرتاان امسه is_palindrome يأخذ حمارف كقرينة و يرجع True ان اكنت منتاظرة و ال False تذكر أنه ميكنك اس تخدام الاقرتان اجلاهز len ملعرفة عدد احلروف. احلل:.http://thinkpython.com/code/palindrome_soln.py مترين 6.7 العدد a هو أس العدد b اكتب اقرتاان امسه is_power يأخذ برمرتين a و b أس b تذكر بأن عليك التفكري حباةل الاصل. و يرجع True ان اكن a هو مترين 6.8 القامس املشرتك الاعظم ل a و b هو أكرب عدد يقسم الرمقني عليه دون ابق احدى طرق اجياد ق-م-أ لرمقني هو اجياد ابيق قسمة a عىل b مث يكون r) gcd (a, b) = gcd (b, كحاةل أصل ميكننا اس تخدام. gcd (a, 0) = a اكتب اقرتاان امسه gcd يأخذ برمرتين a و b و يرجع قامسهام املشرتك الاعظم. عرفان: بين هذا المترين عىل مثال من "هيلك و تأويل الربامج احلاسوبية" ل أبلسون و سسمن.
فكر بايثون 60 السابع الفصل التكرار تعدد التعيينات 7.1 قد تكون قد اكتشفت لوحدك جواز وجود أكرث من تعيني ملتغري واحد التعيني اجلديد جيعل املتغري يشري اىل قمية جديدة )و يتوقف عن الاشارة اىل السابقة(. bruce = 5 print bruce, bruce = 7 print bruce خمرجات هذا الربانمج يه 5 7 لنه عند طباعة bruce الاوىل اكنت قميته 5 و يف الثانية اكنت 7 الفاصةل يف هناية سطر print الاوىل متنع الانتقال لسطر جديد ذلكل ظهرت اهلرجات عىل نفس السطر. الشلك 7.1 يبني كيف يبدو تعدد التعيينات يف رمس احلاةل. من املهم عند تعدد التعيني التفريق بني معلية تعيني و معلية مساواة و لن ابيثون يس تخدم اشارة التساوي )=( للتعيينات فقد منيل اىل تفسري عبارة ك a = b عىل أهنا عبارة مساواة و هذا غري حصيح. ابدئا ذي بدئ املساواة عالقة متاثلية و التعيني ل مفثال يف الرايضيات ان اكنت = 7 قانونية أما = 7 a فليست. a يف ابيثون a = = 7 a فان 7 و أكرث من هذا يف الرايضيات تكون عبارات املساواة اما صائبة أو خاطئة طوال الوقت يف ابيثون عبارة التعيني قد تساوي متغريين لكن ليس ابلرضورة أن يظال متساويني. السطر الثالث يغري قمية a = 5 b = a # a and b are now equal a = 3 # a and b are no longer equal a و ليس b اذن فقد زال تساوهيام رمغ الفائدة الكبرية للعيينات املتعددة الا أن عليك تويخ احلذر عند استعاملها. ان تبدلت قمي املتغريات كثريا سيصبح من الصعب قراءة و عالج أخطاء النص الربجمي. الشلك 7.1: رمس احلاةل
فكر بايثون 61 7.2 حتديث املتغريات x = x +1 احد أشاكل التعيني املتعدد هو التحديث حيث تعمتد القمية اجلديدة ملتغري عىل سابقهتا. معىن هذا "خذ القمية احلالية ل x أضف لها 1 مث حدهثا ابلقمية اجلديدة". ان حاولت حتديث متغري غري موجود س تحصل عىل خطأ لن ابيثون يقمي اجلانب الامين قبل تعيني القمية ل x: قبل أن تمتكن من حتديث متغري عليك أن تس هتل املتغري أول عادة بتعيني بس يط: حتديث املتغري ابضافة 1 تدعى increment أما بطرح 1 فتسمى.decrement >>> x = x + 1 NameError: name 'x' is not defined >>> x = 0 >>> x = x + 1 عبارة 7.3 طاملا while أكرث ما ت س تخدم احلواسيب فيه هو أمتتة املهام املتكررة فتكرار معل املهام نفسها و بدون أخطاء يه ما أفضل يقوم به احلاسوب و ما يفتقر اليه البرش. لقد رأينا برانجمني و لكون التكرار مفهوم شائع و رف 4.2 س نعود لها لحقا. countdown وprint_n يس تخدمان الاجرتار لعادة القيام ابلعملية هذا يدعى أيضا ابلتكرار. ابيثون عدة مزااي لغوية تسهل اس تخدامه احداها يه عبارة for اليت رأيناها يف القسم املزية الاخرى يه عبارة.while هذه نسخة من countdown تس تخدم عبارة : while def countdown(n): while n > 0: print n n = n-1 print 'Blastoff!' ابماكنك قراءة عبارة while كام لو اكنت اجنلزيية )كذكل: "طاملا" كام لو اكنت عربية( و يه تعين "طاملا n أكرب من صفر اطبع قمية n مث أنقصها مبقدار 1 و عندما تصل اىل الصفر أظهر اللكمة "Blastoff! رمسيا أكرث هذا سريان النتفيذ لعبارة : while -1-2 -3 ق مي الرشط ابخراج ان اكنت النتيجة ان اكنت النتيجة اما True أو.False False اخر ج من عبارة نفذ ما يف منت و أمكل التنفيذ من العبارة اليت تلهيا. مث عد اىل اخلطوة 1. while while True يدعى هذا النوع من رساين التنفيذ ب احللقة Loop لن اخلطوة الثالثة عادت مرة أخرى اىل بداية التنفيذ.
فكر بايثون 62 جيب عىل منت احللقة أن يغري قمية متغري أو أكرث ليك ينهتيي الرشط اىل False في وقف ادلوران يف احللقة. و الا فس يكون ادلوران يف حلقة اىل البد و عندها تصبح احللقة ل منهتية )حلقة مفرغة(. علامء احلاسوب يرون التعبري عىل علب الشامبو ظريفا "صوبن اشطف مث كرر" يذكرمه ابحللقة املفرغة. يف حاةل countdown أثبتنا أن ادلوران يف احللقة سيتوقف لن قمية n منهتية و لننا نرى بأن قمية لك مرة ت دور هبا يف احللقة اىل أن تنهتيي اىل الصفر يف حالت اخرى يكون من الصعب الثبات: أخذة ابل صغر يف n def sequence(n): while n!= 1: print n, if n%2 == 0: # n is even n = n/2 else: # n is odd n = n*3+1 الرشط يف هذه احللقة هو أن 1=!n اذن فادلوران سيسمتر اىل أن تصبح n تساوي 1 مما جيعل الرشط.false يف لك دورة يف احللقة خي رج الربانمج قمية ل n مث يفحص اذا ما اكنت فردية أو زوجية ان اكنت زوجية فس ت قسم 2 و ان اكنت فردية فست ستبدل قمية n ب 3+1*n مثال ان اكن القرينة اليت مر تر اىل فالتسلسل اهلرج هو.10, 5, 16, 8, 4, 2, 1 n sequence يه عىل 3 مبا أن n تزداد أحياان و تنقص أخرى فال يوجد ما يربهن بأهنا س تصل اىل 1 أو أن الربانمج سيتوقف. لقمي معينة ل n نس تطيع الربهنة مثال ان اكنت القمية الابتدائية يه الس 2 فس تكون قمية n زوجية يف لك مرة تدور فهيا يف احللقة اىل أن تنهتيي اىل 1 س ينهتيي املثال السابق هبذا املسار كهذا ان بدئ ب 16. السؤال الاصعب هو هل ميكننا اثبات أن الربانمج سيتوقف للك قمي الاماكنية! أنظر: n مل يمتكن أحد حىت الان من اثبات أو نفي هذه http://en.wikipedia.org/wiki/collatz_conjecture مترين 7.1 أعد كتابة الاقرتان print_n من القسم 5.8 مس تخدما مبدأ التكرار بدل من مبدأ الاجرتار. الكبح 7.4 break أحياان ل تمتكن من معرفة اذا ما حان الوقت لالقرتان أن يتوقف قبل أن تصل منتصف املنت. يف هكذا حالت ميكنك اس تخدام عبارة break للقفز خارج احللقة. فعىل سبيل املثال افرتض أنك تريد من الربانمج أن يرص عىل طلب مدخالت من املس تخدم لكن ان طبع املس تخدم done يتوقف عن الارصار ابماكنك كتابة: while True: line = raw_input('> ') if line == 'done': break print line print 'Done!' رشط احللقة هو True و اذلي س يكون متحققا دامئا اذن فهذه احللقة س تظل تعمل اىل أن تصادف عبارة.break
فكر بايثون 63 يف لك دورة س يصغي انلث للمس تخدم بقوس زاوي. فان طبع املس تخدم done س تخرجنا عبارة و ال فسريدد الربانمج ما يطبعه املس تخدم مث يعود اىل رأس احللقة هذا تشغيل الربانمج: break من احللقة > not done not done > done Done! هذه الطريقة لكتابة حلقة while شائعة لهنا تس تطيع حفص الرشط يف موضع من احللقة )و ليس فقط يف مقهتا(. و متكننا من التعبري حبزم عندما نريد للتنفيذ أن يتوقف ) قف عند حدوث هذا ( بدل من ) اسمتر حىت حيدث هذا ( اجلذور الرتبيعية 7.5 تس تخدم احللقات كثريا حلساب النتاجئ العددية عن طريق البدء بقمية مقربة للجواب مث اس تخدام التكرار لتحسينه. مثال احدى طرق حساب اجلذر الرتبيعي يه طريقة نيوتن. افرض أن دليك عدد a و تريد معرفة جذره الرتبيعي. ان ابتدأت بأي توقع x فباماكنك حساب توقع أقرب حسب املعادةل التالية: لنفرض مثال أن a اكنت 4 و x اكنت 3: >>> a = 4.0 >>> b = 3.0 >>> y = (x + a/x)/2 >>> print y 2.166666667 y = x + a/x 2 هذه النتيجة أقرب من 3 اىل اجلواب الصحيح )2 = 4 (. الان ان اس تخدمنا هذه النتيجة و دورانها يف نفس املعادةل س نقرتب أكرث اىل اجلواب الصحيح: بعد بضعة حتديثات س يكون اجلواب تقريبا مئة ابملئة: >>> x = y >>> y = (x + a/x)/2 >>> print y 2.00641025641 >>> x = y >>> y = (x + a/x) / 2 >>> print y 2.00001024003 >>> x = y >>> y = (x + a/x) / 2 >>> print y 2.00000000003 حنن ل نعمل مس بقا ما هو عدد اخلطوات اليت سيتطلهبا اجياد اجلواب الصحيح الا أننا س نعمل بأننا وصلنا اىل اجلواب الصحيح لن سلوك احللقة سيتغري: >>> x = y >>> y = (x + a/x) / 2 >>> print y 2.0 >>> x = y
فكر بايثون 64 >>> y = (x + a/x) / 2 >>> print y 2.0 عندما تصبح y == x ابماكننا التوقف. هذه حلقة تبدأ بتوقع أ ويل مث تظل حت x س نه اىل أن تتوقف احللقة عن التغري: while True: print x y = (x + a/x) / 2 if y == x: break x = y.float هذه الطريقة تعمل جيدا ملعظم قمي a الا أهنا خطرة يف العموم عند حفص التساوي ل قمي النقاط العامئة "حصيحة تقريبا" فقط: فال ميكن متثيل الاعداد ادلورية اكلثلث و الالدورية مثل 2 مئة ابملئة عن طريق الاعداد العامئة. المن من حفص ان اكنت لك من الارتفاع للفرق بيهنام حيث x و y متساويتان هو اس تخدام الاقرتان اجلاهز abs اذلي حيسب القمية املطلقة أو If (y-x)<epsilon: break epsilon لها قمية ما مثل 0.0000001 اليت حتدد ماهو "القريب مبا فيه الكفاية". مترين 7.2 كبسل هذه احللقة يف اقرتان امسه square_root يأخذ a كربمرت مث خيتار قسمة معقوةل ل x و يرجع توقعا للجذر الرتبيعي ل a. 7.6 اخلوارزميات Algorithms اكنت طريقة نيوتن مثال للخوارزميات: معلية رايضية حلل فئة من املسائل )حساب اجلذور الرتبيعية يف هذه احلاةل(. ليس من السهل تعريف اخلوارزمية لكن قد يقر ب معناها البدء بيشء ليس خوارزميا. يف املدرسة عندما تعلمت جداول الرضب خلانة واحدة اكن عليك تذكر جدول الرضب اكمال أي أنك حفظت مئة حل ملئة مسأةل. هذا النوع من املعرفة ليس خوارزميا. الا أنه ان كنت "كسول" حيهنا لكنت قد غششت بأن تعلمت بضعة خدع مفثال لتوجد حاصل رضب س يف 9 كنت تكتب س - 10 يف اخلانة الاوىل و 10 س يف اخلانة الثانية هذه اخلدعة يه طريقة عامة حلل حاصل رضب 9 يف الارقام ذات اخلانة الواحدة. هذا الاسلوب اكن خوارزميا! كذكل اكنت املهارات اليت تعلمهتا يف امجلع ابلمحل و الطرح ابلقرتاض و القسمة الطويةل لكها خوارزميات. من صفات اخلوارزميات أهنا ل تتطلب ذاكءا للقيام هبا يه فقط معليات مياكنيكية تتبع فهيا لك خطوة اخلطوة اليت س بقهتا بناءا عىل قوانني سهةل. برأيي أنه من السخف لالنسان أن مييض أوقاات طويةل يف املدارس يتعمل كيف ينفذ اخلوارزميات اليت حرفيا ل تتطلب أي ذاكء. يف املقابل فان معلية تصممي اخلوارزميات يه املثرية و هبا حتد ثقايف و يه جزء مركزي مما نسميه الربجمة. بعض الاش ياء اليت يقوم هبا الناس بشلك طبيعي و بال صعوبة أو حىت بال وعي تكون الاصعب عند حماوةل التعبري عهنا خوارزميا. مثال جيد لهذا هو فهم اللغات الطبيعية لكنا نتلكمها )نفعلها( لكن مل يمتكن أحد حىت الان أن يفرس "كيف" نفعلها ليس تفسريا عىل شلك خوارزمية عىل الاقل.
عالج الاخطاء 7.7 فكر بايثون 65 عندما تبدأ بكتابة برامج أكرب قد جتد نفسك غارقا ملدة أطول يف عالج الخطاء. نص برجمي أطول يعين احامتلت أكرث للخطأ و أمكنة أكرث ليختئب فهيا البق. احدى طرق تقليل الوقت املستنفذ يه "عالج الخطاء ابلتنصيف" فان اكن دليك 100 سطر يف الربانمج س تأخذ يف العادة 100 خطوة للبحث عن الخطاء و عالهجا. بدل من ذكل حاول تقسمي املشلكة اىل نصفني احبث يف منتصف النص أو ابلقرب منه عن قمية متوسطة تس تطيع متابعهتا أضف عبارة print أو أي شي أخر هل أثر تأكيدي مث شغل الربانمج. أن اكنت نقطة البحث الوسطى هذه غري حصيحة فالبد أن يكون اخلطأ يف النصف الاول من النص و ان اكنت حصيحة س يكون يف النصف الثاين. يف لك مرة تقوم بفحص كهذا تن صف عدد السطور اليت بقي عليك البحث فهيا عن اخلطأ بعد 6 خطوات )أقل من املئة خطوة السابقة( س يتبقى كل سطر أو سطرين من النص الربجمي لتفحصه عىل الاقل نظراي. معليا ل يكون موقع منتصف املشلكة واحضا و أحياان غري قابل للفحص و من غري املعقول أن تعد سطور الربانمج لتصل اىل املنتصف. بدل من ذكل فكر ابلماكن اليت تتوقع وجود خطأ فهيا و الاماكن اليت من السهل وضع مقسوم هبا مث اخرت البقعة اليت يكون احامتل اختباء البقة قبلها أقرب من احامتهل بعدها. املعاين 7.8 تعدد التعيينات :multiple assignment معل أكرث من تعيني ملتغري خالل تشغيل الربانمج. حتديث :update تعيني تعمتد فيه القمية اجلديدة ملتغري عىل القدمية. اس هتالل :initialization تعيني يعطي القمية الابتدائية ملتغري سيمت حتديثه. زايدة : increment حتديث تزاد فيه قمية املتغري )غالبا ب 1(. انقاص :decrement حتديث ي نقص من قمية املتغري. تكرار :iteration تنفيذ متكرر ملموعة من العبارات ابس تخدام الاجرتار أو احللقات. حلقة مفرغة :infinite loop حلقة ل توف هبا رشوط الاقفال. 7.9 مترين متارين 7.3 math.sqrt لتفحص خوارزمية اجلذر الرتبيعي الانف ذكرها يف هذا الفصل ابماكنك مقارنهتا ابلقرتان اجلاهز اكتب اقرتاان امسه test_square_root يطبع جدول كهذا: 1.0 1.0 1.0 0.0 2.0 1.41421356237 1.41421356237 2.22044604925e-16 3.0 1.73205080757 1.73205080757 0.0 4.0 2.0 2.0 0.0 5.0 2.2360679775 2.2360679775 0.0 6.0 2.44948974278 2.44948974278 0.0 7.0 2.64575131106 2.64575131106 0.0
فكر بايثون 66 مترين 8.0 2.82842712475 2.82842712475 4.4408920985e-16 9.0 3.0 3.0 0.0 العمود الاول عدد a الثاين يكون اجلذر الرتبيعي حمسواب ابس تخدام الاقرتان من القسم 7.5 و الثالث يكون اجلذر الرتبيعي حمسواب ابس تخدام math.sqrt و العمود الرابع هو القمية املطلقة للفرق بني التوقعني. >>> eval('1 + 2 * 3') 7 >>> eval('math.sqrt(5)') 2.2360679774997898 >>> eval('type(math.pi)') <type 'float'> eval 7.4 الاقرتان اجلاهز eval يأخذ حمارف و يقميها ابس تخدام مف رس ابيثون مثال: اكتب اقرتاان امسه يطبع نتيجة التقيمي. eval_loop يكرر طلب الادخال من املس تخدم مث يأخذ املدخالت و يقميها ابس تخدام عىل الاقرتان الاس مترار حىت يطبع املس تخدم done مث يرجعة قمية اخر تعبري قميه مترين 75 الرايضيايت رسينيفازا رامانوجان وجد متسلسةل لهنائية ميكن استعاملها لجياد تقريب ل 1 /ط: 1 π = 2 2 9801 ( 4k)! (1103 + 26390K ) (k!) 4 396 4k k =0 و اكتب اقرتاان امسه estimate_pi يس تخدم هذه املعادةل حلساب و ارجاع تقريب ل ط جيب اس تخدام while حلساب املاميع حىت يصبح اخر مجموع أقل من 15-1e ( ابيثون يكتهبا هكذا للتعبري عن 15-10( ميكنك مقارنة التنيجة ب.math.pi احلل:.http://thinkpython.com/code/pi.py
فكر بايثون 67 الفصل الثامن انلارف 8.1 انلارف يه تسلسالت انلارف )الطالمس ان أردت( يه سالسل من الاشاكل و احلروف و الارقام و ميكنك الوصول اىل لك من احلروف )أو الاشاكل و الارقام( مبؤثر احلارصة[]: ختتار العبارة الثانية الشلك الاول من fruit مث تعينه ل.letter >>> fruit = 'banana' >>> letter = fruit[1] التعبري اذلي بني احلارصتني يدعى املؤرش index يؤرش املؤرش اىل أي من حروف السلسةل تريد )و منم الامس(. ال أنك قد ل حتصل ما توقعت: اذن ف b يه احلرف الصفر >>> letter = fruit[0] >>> print letter b من banana, و كذكل ف n هو احلرف الثاين. ابماكنك اس تخدام أي تعبري مكؤرش مبا فهيا املتغريات و العوامل لكن جيب أن تكون قمية املؤرش عدد حصيح و ال فس تحصل عىل خطأ: >>> letter = fruit[15] TypeError: string indices must be integers, not float len 8.2 الاقرتان اجلاهز len يرجع عدد حروف انلارف: فليك حتصل عىل الرمق الاخري يف انلارف قد تغريك الكتابة اكلتايل: السبب يف هذا اخلطأ IndexError هو أنه ل يوجد حرف يف فس ننهتيي ب 5 اذن ليك حتصل عىل احلرف الاخري عليك طرح >>> fruit = 'banana' >>> len(fruit) 6 length = len(fruit) last = fruit[length] IndexError: string index out of range banana رمق مؤرشه 6 فامب أننا ابتدأان العد بصفر 1 من nlength
فكر بايثون 68 >>> last = fruit[length-1] >>> print last a أو ميكنك كبديل اس تخدام أرقام املؤرشات السالبة و اليت تبدأ العد عكس يا من هناية انلارف اىل بدايهتا فالتعبري fruit[-1] هو اخر حرف و [ fruit[-2 هو احلرف قبل الاخري و هكذا. 8.3 مترين املرور ابس تخدام for كثرية يه العمليات احلوسبية اليت هبا تمت معاجلة انلارف حرفا تلو الخر هذه العمليات عاد ىة ما تبدا يف بداية انلارف مث ختتار لك حرف بدوره تفعل شيئا ما هبذا احلرف مث تسمتر حىت الهناية. هذا المنط من املعاجلات يسمى املرور traversal حلقة while يه احدى طرق كتابة املرور: index = 0 while index < len(fruit): letter = fruit[index] print letter index = index + 1 متر هذه احللقة يف انلارف مث تعرض لك حرف عىل سطر لوحده رشط هذه احللقة اكن( len(fruit index < فعندما تتساوى قمية index مع طول انلارف تكون نتيجة الرشط false و لن ينفذ منت احللقة اخر حرف تصهل احللقة هو احلرف اذلي مؤرشه len(fruit)-1 و هو اخر حرف يف السلسةل. 8.1 اكتب اقرتاان يأخذ حمارف كقرينة مث يعرض حروفها معكوسة و لك حرف يف سطر. طريقة أخرى لكتابة حلقة مرور يه عن طريق حلقة for char in fruit: print char :for يف لك دورة يف احللقة فان احلرف التايل س يعني للمتغري char و سيسمتر التدوير اىل أن تنهتيي لك احلروف. املثال التايل يبني طريقة اضافة حمارف و حلقة للبطيطات لروبرت ملكوسيك اكنت أسامء البط اسامءها ابلرتتيب: for لتوليد ألفبائية )حسب التسلسل الاجبدي(. يف كتاب افسح الطريق Jack, Lack, Mack, Nack, Pack و Quack هذه احللقة خت رج الشلك 8.1: مؤرشات رشاحئ prefixes = 'JKLMNOPQ' suffix = 'ack' for letter in prefixes: print letter + suffix Jack Kack امل خرج هو:
فكر بايثون 69 Lack Mack Nack Oack Pack Qack طبعا هذا غري حصيح لن هتجئة Ouack و Quack غري حصيحة. مترين 8.2 عدل الربانمج لتصحح اخلطأ. انلارف رشاحئ 8.4 أي قطعة من حمارف تسمى رشحية slice اختيار رشحية يشبه اختيار حرف: >>> s = 'Monty Python' >>> print s[0:5] Monty >>> print s[6:12] Python العامل ]n:m[ يرجع جزء من انلارف مبتدءا ابحلرف اذلي يف املوقع n و حىت احلرف اذلي يف املوقع m متضمنا احلرف الاول و لكن ليس الاخري هذا الترصف ل يتالءم مع البدهية لتسهيل الامر ختيل أن املؤرشات تشري اىل ما بني مواقع احلروف كام يف الشلك 8.1. ان مل تكتب قمية املؤرش الاول )اذلي قبل النقطتني( يبدأ اختيار الرشحية من بداية انلارف و ان مل تكتب املؤرش الاخري تكون هناية الرشحية يه هناية انلارف: >>> fruit = 'banana' >>> fruit[:3] ban >>> fruit[3:] ana ان اكنت قمية املؤرش الاول أكرب من أو تساوي الثاين فالنتيجة يه حمارف فارغة و ستمتثل بعالميت اقتباس: انلارف الفارغة ليس هبا حروف و طولها 0 لكن عدا ذكل فهيي متاما كي حمارف أخرى. مترين >>> fruit = 'banana' >>> fruit[3:3] '' 8.3 مبا أن fruit يه حمارف مفا معىن fruit]n[ ل ت ع دل ثبيتة انلارف 8.5 من املغري اس تخدام ][ اىل يسار التعيني بني ة تغيري حرف يف انلارف: >>> greeting = 'Hello, World!' greeting[0] = 'J' TypeError: 'str' object does not support item assignment الاكئن هنا هو انلارف و العنرص هو احلرف اذلي حاولت تعيينه. يف الوقت احلارض سنعترب الاكئن هو نفسه القمية لكننا س هنذب هذا التعريف لحقا العنرص هو أحد القمي يف تسلسل ما.
فكر بايثون 70 سبب اخلطأ هو أن انلارف ل تعد ل أي أنه ليس ابلماكن تغيري حمارف موجودة. البديل لهذا هو اجياد حمارف جديدة مث التعديل علهيا: >>> greeting = 'Hello, World!' >>> new_greeting = 'J' + greeting[1:] print new_greeting Jello, World! أضاف هذا املثال حرف أول جديد لرشحية من greeting و مل تؤثر يف انلارف الاصلية. البحث 8.6 ماذلي يفعهل الاقرتان التايل: def find(word, letter): index = 0 while index < len(word): if word[index] == letter: return index index = index + 1 return -1 حرفا و find اكن هذا املثال الاول حيث نرى عبارة return داخل حلقة فان تصادف أن word[index] == letter فان الاقرتان س يخرج من احللقة و يرجع فورا. من حيث املعىن ف find يه املقابل للرمز ][ فبدل من أخذ مؤرش مث انزتاع احلرف املقابل هل تأخذ جتد املؤرش اذلي عنده يظهر احلرف. ان مل يوجد احلرف فس ريجع الاقرتان -1. ان مل يظهر احلرف يف انلارف فان الربانمج س ينهتيي بشلك عادي و يرجع القمية -1. 8.4 مترين هذا المنط من احلوس بة مرور عىل تسلسل و الرجوع عندما جند ما نبحث عنه يسمى البحث search عدل find حبيث يصبح لها برمرت اثلث يكون مؤرشايف word حيدد أين سيبدأ البحث. التدوير و العد 8.7 ي عد الربانمج التايل عدد املرات اليت يظهر فهيا احلرف a يف حمارف: مترين word = 'banana' count = 0 for letter in word: if letter == 'a': count = count + 1 print count count يوحض هذا املثال منط اخر من امناط احلوسبة يسمى العداد.counter ي س هتل املتغري بصفر مث تزداد قميته يف لك مرة جيد فهيا a و عندما ت رتك احللقة حيتفظ count ابلنتيجة و اليت يه عدد a يف السلسةل. 8.5 كبسل النص الربجمي يف اقرتان و مس ه count مث معمه حبيث يأخذ انلارف و احلرف كقرينتني. مترين 8.6 أعد كتابة هذا الاقرتان حبيث أنه بدل من املرور يف انلارف فانه يس تخدم النسخة ذات الثالثة برمرتات يف find يف القسم السابق.
انلارف طرق 8.8 فكر بايثون 71 الطريقة )method( تشبه الاقرتان تأخذ قرائن و ترجع قمية الا أن حنوها خيتلف. مفثال الطريقة انلارف و ترجع حمارف جديدة جاعةل لك حروفها كبرية: و بدل من من اس تخدام بناء الاقرتان upper upper(word) هذا المنط من التنويت ابلنقاط dot notation حيدد امس الطريقة علهيا.word الاقواس الفارغة تعين أن هذه الطريقة ل تأخذ قرائن. فان كتابة الطرق تكون هكذا.word.upper() ت خذأ >>> word = 'banana' >>> new_word = word.upper() >>> print new_word BANANA upper و امس انلارف اليت س تطبق الطريقة نداء الطريقة يدعى اس تدعاء invocation )نداء الاقرتان يسمى )call و يف هذه احلاةل نقول: حنن نس تدعي upper عىل.word تبني أن هناك طريقة للمحارف تسمى find و تقوم بنفس معل الاقرتان اذلي كتبناه للتو: يف هذا املثال اس تدعينا find احلق أن >>> word = 'banana' >>> index = word.find('a') >>> print index 1 عىل word find و مرران احلرف اذلي نبحث عنه كربمرت. أمع من الاقرتان اذلي كتبناه فبوسعها اجياد أجزاء من انلارف: و بوسعها أيضا أخذ املؤرش حيث يبدأ البحث كقرينة اثنية: و كقرينة اثلثة تأخذ املؤرش حيث ينهتيي البحث: فشل هذا البحث لن b ل تظهر يف النطاق من 1 اىل 2 )ل يتضمن 2(. مترين 8.7 هناك طريقة للمحارف اس تدعاءا يرجع عدد a يف >>> word.find('na') 2 >>> word.find('na', 3) 4 >>> name = 'bob' >>> name.find('b', 1, 2) -1 تسمى count.banana و يه شبهية ابلقرتان اذلي كتبناه يف المترين السابق. اقرأ واثئقها مث اكتب مترين 8.8 اقرأ واثئق طرق انلارف فقد يفيدك التدرب عىل بعضها لتتعمل كيف تس تخدم هناك فائدة خمصوصة ل strip و.replace الواثئق تس تخدم حنوا قد يكون مشوشا مثال يف([[ end find(sub[, start[, اختيارية ف sub مطلوبة لكن start اختيارية و ان مض نت start تصبح end اختيارية. الاقواس تعين قرائن
8.9 املؤثر in فكر بايثون 72 اللكمة in يه رمز بوليان تأخذ حمارفني و ترجع اما True ان ظهرت انلارف الاوىل كجزء من الثانية: >>> 'a' in 'banana' True >>> 'seed' in 'banana' False مثال: الاقرتان التايل يطبع لك حروف word1 اليت تظهر يف :word2 ان أأحسن اختيار أسامء املتغريات فان ابيثون ي قرأ كام تقرأ الاجنلزيية ميكن قراءة هذه احللقة اكلتايل: def in_both(word1, word2): for letter in word1: if letter in word2: print letter for (each) letter in (the first) word, if (the) letter (appears) in (the second) word, print (the) letter هذا ما س تحصل عليه ان قا نرت التفاح ابلربتقال: in_both('apples', 'oranges') a e s انلارف مقارنة 8.10 مؤثرات النسبة تعمل عىل انلارف. ليك نرى ان اكنت حمارفتني متساويتني: مؤثرات اخرى مفيدة لوضع احلروف يف ترتيب اجبدي: if word == 'banana': print 'All right, bananas' if word < 'banana': print 'Your word,' + word + ', comes before banana' elif word > 'banana': print 'Your word,' + word + ', comes after banana' else: print 'All right, bananas' ل يتداول ابيثون الاحرف الكبرية و الاحرف الصغرية كام يتداولها الناس. لك احلروف الكبرية تأيت قبل الصغرية فان: before, banana تأيت قبل Your word, Pineapple من طرق التعامل مع هذه املشلكة حتويل لك احلروف اما اىل صغرية أو كبرية قبل املقارنة. انقش هذه املعلومة يف رأسك س تفيدك ان واهجت رجال مسلحا بأانانسة.
عالج الاخطاء 8.11 فكر بايثون 73 عندما تس تخدم املؤرشات indices للمرور يف قمي يف تسلسل يكون التعرف عىل بداية و هناية املرور خمادعا. التايل اقرتان يفرتض أنه يقارن بني لكمتني و يرجع True ان اكنت احداها معكوس الاخرى الا أن به خطأين: def is_reverse(word1, word2): if len(word1)!= len(word2): return False i = 0 j = len(word2) while j > 0: if word1[i]!= word2[j]: return False i = i+1 j = j-1 return True عبارة if الاوىل تفحص اذا ما اكن لللكمتني نفس الطول ان اكن ل سرتجع False مبارشة بعدها و اىل هناية الاقرتان ميكننا افرتاض ان اللكامت متساوية يف الطول هذا مثال عىل منط الويص يف كتابة النصوص الربجمية كام يف القسم.6.8 i و j مؤرشين: جتتاز i السلسةل word1 ق دما بيامن جتتاز j السلسةل word2 رجوعا ان وجدان حرفني غري متشاهبني سرنجع False مبارشة أما ان اجزتان احللقة اكمةل و لك احلروف متشاهبة فسرنجع.True ان امتحنا هذا الاقرتان بلكميت pots و stop سنتوقع احلصول عىل True الا أننا س نحصل عىل :IndexError >>> is_reverse('pots', 'stop')... word1 'pots' word1 'pots' i 0 i 3 الشلك : 8.2 رمس احلاةل File "reverse.py", line 15, in is_reverse if word1[i]!= word2[j]: IndexError: string index out of range لعالج خطأ كهذا خطويت الاوىل س تكون طباعة قمي املؤرشات مبارشة قبل موقع ظهور اخلطأ: while j > 0: print i, j # print here if word1[i]!= word2[j]: return False i = i+1 j = j-1 >>> is_reverse('pots', 'stop') عندما اشغل الربانمج الان سأحصل عىل معلومات أكرث:
فكر بايثون 74 خالل أول دورة يف احللقة اكنت قمية j يه 4 و يه ابلفعل خارج نطاق انلارف 3 و عليه فالقمية الابتدائية للمؤرش j جيب أن تكون.len(word2)-1 ان أصلحت هذا اخلطأ و شغلت الربانمج سأحصل عىل: 0 4... IndexError: string index out of range pots فقمية املؤرش لخر حرف يه >>> is_reverse('pots', 'stop') 0 3 1 2 2 1 True يف هذه املرة حصلنا عىل اجلواب الصحيح لكن يبدو أننا مرران يف احللقة ثالث مرات فقط و هذا مثري للشك. ليك نس توحض ما اذلي حيدث يفيدان رمس حاةل للربانمج خالل التكرار الاول يظهر اطار is_reverse يف الشلك 8.2. أخذت بعض احلرية يف ترتيب املتغريات يف الاطار و وضع اسهم منقطة لبيان أن قمي i و j.word2 مترين 8.9 انطالقا من هذا الرمس نفذ الربانمج عىل الورق مغريا قمي الاقرتان. i و j تشري حلروف يف word1 و يف لك تكرار جد و حصح اخلطأ يف هذا املعاين 8.12 اكئن :object أي يشء قد يشري اليه متغري ابماكنك يف الوقت احلايل اس تعامل قمية و اكئن للتعبري عن نفس اليشء. تسلسل :sequence مجموعة مرتبة أي: مجموعة من القمي مرتبة حبيث يكون للك قمية عدد حصيح مكؤرش. عنرص :item احدى القمي يف مجموعة مرتبة. مؤرش :index عدد حصيح يس تعمل لختيار عنرص يف مجموعة مرتبة. رشحية : slice جزء من حمارف حيددها نطاق املؤرشات. سلسةل فارغة :empty string حمارف ليس هبا حروف و طولها صفر متثلها عالميت اقتباس. غري متبدل :immutable صفة التسلسل اذلي ل ميكن التعيني لعنارصه. مرور :traverse القيام بنفس العملية للك العنارص يف تسلسل. حبث :search منط من أمناط املرور حبيث تتوقف العملية عندما جتد ما تبحث عنه. عداد : counter متغري يس تخدم لعد يشء ما عادة يس هتل بقمية 0. طريقة : method اقرتان مرتبط باكئن يس تدعى بمنط التدوين ابلنقاط. استدعاء :invocation عبارة لنداء الطريقة.
متارين 8.14 فكر بايثون 75 مترين 8.10 بوسع رشحية انلارف أن تأخذ مؤرش اثلث امسه size" "step و هو عدد الامكنة بني احلروف املتتالية فان اكنت تساوي 2 س يعين حرف نعم و حرف ل و 3 تعين حرف نعم و حرفني ل... خل و step size قميهتا 1- س تخرتق لك اللكمة عكس يا و هكذا ف >>> fruit = 'banana' >>> fruit[0:5:2] 'bnn' ]nn-1[ س تودل حمارف معكوسة. اس تخدم هذا املعىن لكتابة نص برجمي من سطر واحد بدل من is_palindrome يف المترين 6.6 مترين 8.11 مجيع الاقرتاانت التالية هتدف اىل التحقق اذا ما اكنت انلارف حتتوي عىل حروف صغرية ال أن بعضها خطأ ارشح لك اقرتان مهنا )عىل فرض أن الربمرت حمارف(. def any_lowercase1(s): for c in s: if c.islower(): return True else: return False def any_lowercase2(s): for c in s: if 'c'.islower(): return 'True' else: return 'False' def any_lowercase3(s): for c in s: flag = c.islower() return flag def any_lowercase4(s): flag = False for c in s: flag = flag or c.islower() return flag def any_lowercase5(s): for c in s: if not c.islower(): return False return True مترين 8.12 نظام التشفري ROT13 اكن نظاما ضعيفا اعمتد عىل "تدوير" احلروف يف لك لكمة 13 مزنةل التدوير يعين ازاحة احلرف يف الجبدية و حىت املرور مرة أخرى- ان تطلب المر- يف بداية الجبدية. فان بدلنا A مبا يلهيا بثالثة حروف ستصبح D مثال و ان بدلنا Z مبا يلهيا بواحد تصبح A. اكتب اقرتاان و مسه دورت حسب العدد املعطى. مثال rotate_word يأخذ حمارف و عدد حصيح كربمرتات مث يرجع حمارف فها انلارف الاصلية بعد أن."cubed" ان دورت ب 10- ستصبح "melon" و "jolly" دو رت ب 7 ستصبح "cheer"
قد خيدمك اس تخدام الاقرتان اجلاهز بعض الناكت املسيئة ord فكر بايثون 76 فهو حيول احلرف اىل رمزه الرمقي و chr اليت حتول الرمز الرمقي اىل حرف. عىل الان نرتت مكتوبة ب ROT13 فان كنت حتمتل املزاح الثقيل جدها و فك تشفريها. احلل:.http://thinkpython.com/code/rotate.py
فكر بايثون 77 الفصل التاسع دراسة حاةل: لعبة لكامت 9.1 قراءة قوامئ اللكامت لتطبيق الامترين يف هذا الفصل س نحتاج اىل قامئة ابللكامت الاجنلزيية هذه القوامئ متوفرة بكرثة عىل الان نرتت. لكن أكرثها مالءمة لهدفنا يه احدى القوامئ اليت مجعها و سامه هبا للمكل العام Grady Ward و اكنت جزءا من مرشوع "مويب لكسكون" أنظر.http://wikipedia.org/wiki/Moby_Project يه قامئة من 113809 من لكامت العاب اللكامت املتقاطعة الرمسية أي ان اللكامت اليت حتتوهيا تعترب مقبوةل يف معل اللكامت املتقاطعة و غريها من العاب اللكامت امس امللف يف مجموعة مويب هو 113809of.fic ابماكنك حتميل نسخة ابمس ابسط word.txt منhttp://thinkpython.com/code/words.txt. هذا امللف نص خام مما يعين أنه ميكنك فتحه بأي معاجل نصوص لكن ابماكنك قراءته من ابيثون أيضا فالقرتان اجلاهز open يأخذ امس امللف كربمرت و يرجع اكئن ملف: fin يه الامس الشائع لاكئن امللف للكتابة(. لقراءة اكئن امللف طرق عديدة مهنا النتيجة عىل شلك حمارف: >>> fin = open('words.txt') >>> print fin <open file 'words.txt', mode 'r' at 0xb7f4b380> و عندما تس تخدم الوضع r س يعين أن امللف ف تح للقراءة )عىل عكس w readline اللكمة الاوىل يف هذه القامئة هذه يه "aa" و التسلسل اجلديد اذلان يفصالن هذه اللكمة عن اتليهتا. فتح اليت تقرأ احلروف من امللف حىت تصل اىل السطر التايل مث ت رجع >>> fin.readline() 'aa\rr\n' \r\n و اكئن امللف هذا ل ينىس املاكن اذلي وصل اليه يف امللف فان اس تدعيت يمكل و سريجع كل اللكمة التالية: اللكمة التالية يه aah )و يه لكمة جائزة متاما فتوقف عن النظر ا يل هكذا!( ميثل حرفان فارغان )مسافات بيضاء( : الرجوع و السطر readline مرة اثنية س يعرف من أين >>> fin.readline() 'aah\r\n' ال ان اكن ما يزجعك هو املسافة البيضاء
فالتخلص مهنا مقدور عليه ابلطريقة :strip فكر بايثون 78 ميكنك اس تخدام اكئن امللف كجزء من حلقة for الربانمج التايل يقرأ words.txt مترين 9.1 اكتب برانجما يقرأ املسافات البيضاء(. >>> line = fin.readline() >>> word = line.strip() >>> print word aahed و يطبع لك لكمة فيه عىل سطر: fin = open('words.txt') for line in fin: word = line.strip() print word words.txt مث يطبع اللكامت اليت يزيد عدد حروفها عىل العرشين )دون احتساب متارين 9.2 حلول هذه الامترين متوفرة يف القسم التايل لكن عليك عىل الاقل حماوةل حلها قبل النظر اىل احللول. مترين 9.2 يف العام 1939 كتب ارنست فنسنت رايت رواية من 50000 لكمة و سامها Gadsby و اكنت ل حتتوي عىل احلرف e و مبا أن احلرف e هو أكرث حروف الاجنلزيية اس تعامل ذلكل فان ما قام به ليس ابلمر الهني. " In fact, it is difficult to construct a solitary thought without using that most common symbol. It is slow going at first, but with caution and hours of training you can gradua lly gain facility. حس نا سأكتفي الان اكتب اقرتاان و مس ه has_no_e يرجع True ان مل حتتو اللكمة املدخةل عىل احلرف e. عدل الربانمج من القسم السابق حبيث يطبع اللكامت اليت ليس هبا e فقط مث حيسب النسبة املئوية لللكامت اليت يف قامئة ليس هبا e. مترين 9.3 أكتب اقرتاان و مسه حتتوي عىل أي من احلروف املمنوعة. avoids يأخذ لكمة و حمارف من احلروف املمنوعة مث يرجع True ان اكنت اللكمة ل عدل برانجمك حبيث يطلب من املس تخدم ادخال انلارف املمنوعة مث يطبع اللكامت اليت ل حتتوي عىل أي مهنا هل تس تطيع اجياد تركيبة من 5 حروف ممنوعة حبيث تس تثين أقل عدد من اللكامت مترين 9.4 اكتب اقرتاان و مسه uses_only يأخذ اللكمة مكحارف مث يرجع True ان اكنت اللكمة تس تعمل فقط احلروف اليت يف القامئة هل ميكنك بناء مجةل تس تخدم احلروف acefhlo مجةل غري.Hoe alfalfa مترين 9.5 اكتب اقرتاان و مسه uses_all يأخذ لكمة و حمارف مطلوبة مث يرجع True ان اكنت اللكمة تس تخدم مجيع احلروف املطلوبة عىل الاقل مرة واحدة. مك عدد اللكامت اليت تس تخدم مجيع حروف العةل aeiou و ماذا عن aeiouy مترين 9.6 اكتب اقرتاان امسه is_abecedarian يرجع True ان اكنت حروف اللكمة تظهر ابلرتتيب الاجبدي )ل
مشلكة ابلحرف املكررة(. مك عدد اللكامت اليت ينطبق علهيا هذا احلال :Search البحث 9.3 فكر بايثون 79 هناكل أمر مشرتك بني مجيع الامترين السابقة فميكن حلها مجيعا بمنط البحث اذلي رأيناه يف القسم 8.6 ابسط مثال هو: حلقة for متر عىل احلروف يف.word و ان وجدت e س رتجع ان خرجنا من احللقة بشلك عادي فس يعين أننا مل جند e و عليه يكون امل رجع def has_no_e(word): for letter in word: if letter == 'e': return False return True False مبارشة و الا فس ننتقل اىل احلرف التايل و.True avoid نسخة معممة من أكرث من has_no_e لكن لها نفس البنيان: بدل من قامئة احلروف املمنوعة دلينا قامئة من حروف مسموحة فان وجدان حرفا يف word def avoids(word, forbidden): for letter in word: if letter in forbidden: return False return True ليس available سرنجع.False Usese_all بدل من املرور عىل حروف مشاهبة الا أننا نعكس دور اللكامت و انلارف: def uses_all(word, required): for letter in required: if letter not in word: return False return True word فسرنجع.False متر احللقة عىل احلروف املطلوبة ان مل تظهر يف اللكمة أي من احلروف املطلوبة لو كنت تفكر كعامل حاسوب حقا لتنهبت اىل ان uses_all يه مظهر أخر ملسأةل حلت من قبل و لكنت قد كتبت: def uses_all(word, required): return uses_only(required, word) هذا مثال عىل اسلوب لتطوير الربامج يسمى تذكر املشلكة problem recognition و يعين أن املشلكة اليت بني يديك ذكرتك مبشلكة حللهتا من قبل مث تطبق احلل اذلي طور سابقا عىل املشلكة احلالية 9.3 التدوير ابملؤرشات كتب ت الاقرتاانت يف القسم السابق حبلقات for لنين احتجت اىل حروف انلارف و حسب املؤرشات مل تعنيين. لكن يف is_abecedarian علينا مقارنة حرفيني متجاورين و هذا ابس تخدام حلقة for أمر خمادع: def is_abecedarian(word): previous = word[0] for c in word: if c < previous: return False previous = c
فكر بايثون 80 return True البديل هو اس تخدام الاجرتار: و بديل أخر هو اس تخدام حلقة :while تبدأ احللقة ب 0=i و تنهتيي ب اعتبار املاكن i املاكن احلايل( ابحلرف يف املاكن فان اكن احلرف التايل أصغر def is_abecedarian(word): if len(word) <= 1: return True if word[0] > word[1]: return False return is_abecedarian(word[1:]) def is_abecedarian(word): i = 0 while i < len(word)-1: if word[i+1] < word[i]: return False i = i+1 return True i=len(word(-1 )اس بق اجبداي( i+1.false يف لك مرة تدور يف احللقة س تقارن احلرف يف املاكن i )ميكنك )ميكنك اعتباره املاكن التايل(. من احلرف احلايل فنكون قد اكتشفنا ثغرة يف الالفبائية و نرجع عندها و ان انهتينا من التدوير دون ان جند خطأ مفعناه ان اللكمة قد اجتازت الاختبار. و لتقنع نفسك بأن احللقة انهتت بشلك حصيح خذ مثال ك flossy طول اللكمة 6 فتكون أخر دورة يف احللقة عندما تكون = 4 i و يه املؤرش للحرف الثاين قبل الاخري. يف التكرار الاخري تقارن احلرف الثاين قبل الاخري ابحلرف قبل الاخري و هو مانريده. هذه نسخة من يبدأ الثاين يف الهناية و ينطلق هبوطا. is_palidrome أو ان ذكرك هذا مبشلكة حلت من قبل لكنت كتبت: هذا عىل اعتبار أنك حللت المترين 8.9 )انظر المترين 6.6( تس تخدم مؤرشين يبدأ الاول يف املقدمة و ينطلق صعودا و def is_palindrome(word): i = 0 j = len(word)-1 while i<j: if word[i]!= word[j]: return False i = i+1 j = j-1 return True def is_palindrome(word): return is_reverse(word, word) عالج الاخطاء 9.5 اختبار الربامج صعب اكنت الاقرتاانت يف هذا القسم سهةل نسبيا لنك تس تطيع حفص النتاجئ يدواي. و ان يكن فاختيار
لكامت تس تطيع اختبار لك احامتلت الاخطاء يشء يقع بني الصعب و املس تحيل. بأخذ has_no_e فكر بايثون 81 مكثال هناك حالتان واحضتان يكن حفصهام: فاللكامت اليت هبا e ترجع لن يتعبك اجياد لكمة للكهيام. False True و الاخرى ترجع يف لك من احلالتني هناك حالت فرعية اخرى اقل وضوحا ففي اللكامت اليت حتتوي عىل e عليك اختبار أي مهنا تكون فهيا e يف الاول مث يف الوسط مث يف هناية اللكمة. مث عليك اختبار اللكامت الطويةل و القصرية و القصرية جدا )اكنلارف الفارغة( انلارف الفارغة مثال عىل احلالت اخلاصة و اليت يه احدى احلالت غري الواحضة اليت يعشش فهيا اخلطأ. اضافة حلالت الاختبار اليت اوجدهتا ميكنك حفص برانجمك بقوامئ اللكامت مثل.words.txt ابلنظر يف اهلرجات ميكنك التقاط الاخطاء لكن عليك احلذر: فقد تمتكن من التقاط نوع من الخطاء )اكللكامت اليت جيب الا ت ض من الا أهنا مضمنة( و ل تلتقط النوع الاخر )اكللكامت اليت جيب ان تكون مضمنة و لكهنا ليست كذكل(. يف العموم الاختبار قد يساعدك يف التقاط الاخطاء الا أنه من الصعب اجياد مجموعة متاكمةل من حالت الاختبار و ان وجدت فليس بوسعك التأكد من أن الربانمج حصيح. اختبار الربامج ميك ننا من اظهار البق ان اكن موجودا لكنه ل ميكننا من اظهار عدم وجوده! - ادسغر و. داكسرتا املعاين 9.6 اكئن ملف :file object قمية متثل ملفا مفتوحا. تذكر املشلكة :problem recognition طريقة حلل املشالك ابلتعبري عهنا كشبهية ملشلكة حلت سابقا. حاةل خاصة :special case حاةل اختبار غري منطية أو غري واحضة )و احامتل التعامل معها بشلك حصيح صغري(. متارين 9.7 مترين 97 السؤال مبين عىل اجحية أذيعت عىل برانمج "حديث الس يارة" :Car Talk.http://www.cartalk.com/content/puzzlers "أعطين لكمة هبا ثالثة حروف مشددة متتالية.double letters اليك بعض اللكامت اليت ينطبق m-i-s-s-i-s-sp-p-i علهيا الرشط تقريبا. مثال c-o-m-m-i-t-t-e-e قد تناسب لول ال i اليت تشوهها أو اليت س تكون رائعة لول ال. i الا أنه هناكل لكمة هبا ثالثة حروف مشددة متتالية ابلفعل و عىل حد علمي يه اللكمة الوحيدة. ابلطبع ميكن أن تكون هناكل 500 لكمة أخرى الا أنين قلت عىل حد علمي. ما يه اللكمة اكتب برانجما جيدها. احلل:.http://thinkpython.com/code/cartalk1.py مترين 9.8 هذه اجحية اخرى من.http://wwwcartalk.com/content/puzzlers Car Talk أسوق كنت ذات يوم و حدث أن لفت انتبايه عداد املسافة يف س ياريت للعداد 6 خاانت و "
فكر بايثون 82 لكها للميال الاكمةل فقط فان اكنت س ياريت عند 300000 ميل مثال سأرى 3-0-0-0-0-0. الن ما رأيته ذكل اليوم اكن مثريا. لحظت بأن اخلاانت الاربعة الاخرية اكنت متناظرة أي تقرأ من الميني اىل اليسار كام تقرأ من اليسار اىل الميني مثل 5-4-4-5 يه متناظرة فان اكنت يه اليت عىل العداد س تكون قراءته 3-1-5-4-4-5. بعد ميل واحد أصبحت اخلاانت امخلسة الاخرية متناظرة مثل 3-6-5-4-5-6 مث بعد ميل اخر اصبحت اخلاانت الاربعة الوسطى متناظرة. اس تعد الان: بعد ميل اخر اصبحت اخلاانت الستة مجيعها متناظرة!" "السؤال هو: ماذا اكنت قراءة العداد عندما لحظته يف املرة الاوىل " اكتب برانجما يفحص لك الارقام ذات الس تة خاانت و يطبع أي رمق يفي هذه املتطلبات. احلل:.http://thinkpython.com/code/cartalk2.py مترين 9.9 أيضا من Car Talk ابماكنك حهل ابلبحث..http://www.cartalk.com/content/puzzlers " اكنت دلي مؤخرا زايرة مع الوادلة و انتهبنا اىل أن اخلانتني التني تكوانن معري هام معر الودلة ان ع كسا. مثال ان اكن معرها 73 سأكون 37. مث تساءلنا عن عدد املرات اليت حدث فهيا هذا طوال معرينا الا أن احلديث انتقل ملوضوع أخر فمل نصل للنتيجة. عند عوديت للبيت اكتشفت أن خاانت معرينا اكنت املعكوس ستة مرات حىت الان مث اكتشفت أنه ان طال معرينا فس يحدث نفس الامر بعد بضعة س نوات و ان طال أكرث فس يحدث مرة أخرى بلكامت اخرى فانه قد حيدث مثاين مرات فالسؤال هو: ما هو معري الان " اكتب برانمج ابيثون يبحث عن حل لهذه املسأةل تلميح: قد تكون طريقة zfill لسالسل احلروف مفيدة احلل:.http://thinkpython.com/code/cartalk3.py
فكر بايثون 83 الفصل العارش القوامئ 10.1 القامئة يه تسلسل مثل انلارف فالقامئة يه تسلسل لقمي. اكنت القمي يف انلارف حروفا )حروف و أرقام و أشاكل( أما يف القامئة فميكن للقمي أن تكون أي يشء. القمي يف القامئة تدعى عنارص elements و أحياان items هناكل عدة طرق لجياد قامئة جديدة الاسهل حرص العنارص بني قوسني مربعني )] and [( : [10, 20, 30, 40] ['crunchy frog', 'ram bladder', 'lark vomit'] املثال الاول قامئة هبا أربعة أعداد حصيحة و الثاين قامئة بثالثة حمارف. ليس رشطا أن تكون عنارص القامئة من نفس النوع. القامئة التالية حتتوي عىل حمارف و قمية حقيقية و عدد حصيح و )ها!( قامئة أخرى: القامئة اليت يف داخل اخرى تسمى )معششة(.nested القامئة اليت ليس هبا عنارص تدعى قامئة فارغة و ميكنك معلها بقوسني مربعني فارغني ][. و كام تتوقع فباماكنك تعيني قمي القامئة ملتغريات: ['spam', 2.0, 5, [10, 20]] >>> cheeses = ['Cheddar', 'Edam', 'Gouda'] >>> numbers = [17, 123] >>> empty = [] >>> print cheeses, numbers, empty ['Cheddar', 'Edam', 'Gouda'] [17, 123] [] القوامئ 10.2 ليست ثبيت ىة تع دل حنو عبارة الوصول لحد عنارص القامئة هو نفسه حيدد املؤرش. تذك ر بأن املؤرشات تبدأ ب 0: حنو الوصول اىل حروف انلارف- مؤثر القوسني املربعني ][. التعبري بيهنام >>> print cheeses[0] Cheddar
فكر بايثون 84 cheeses numbers list 0 1 2 list 0 1 'Cheddar' 'Edam' 'Gouda' 17 123 5 empty list و عىل خالف انلارف فان القوامئ ت ع دل فعندما يظهر مؤثر العنرص ذو املؤرش 1 يف الشلك 10.1: رمس احلاةل القوسان عىل يسار التعيني فانه حيدد العنرص اذلي س نعني هل: >>> numbers = [17, 123] >>> numbers[1] = 5 >>> print numbers [17, 5] قامئة numbers و اذلي اكن 123 أصبح الان 5. ابماكنك اعتبار القوامئ كعالقة بني مؤرشات و عنارص هذه العالقة تسمى mapping أي خط اخلطوط أو اخلرائط فلك مؤرش "يرمس خطا" يرشد اىل أحد العنارص. الشلك 10.1 يظهر رمس احلاةل ل number, cheeses, nempty القوامئ ممثةل بصناديق ابمس "list" يف اخلارج و العنارص يف ادلاخل cheeses تشري اىل قامئة من ثالثة عنارص مؤرشة ب 2 1 و 3. حتتوي numbers عىل عنرصين و يبني الرمس أن القمية املعينة للعنرص الثاين أعيد تعييهنا من 123 اىل 5 empty تشري اىل قامئة بال عنارص. مؤرشات القوامئ تعمل مكؤرشات انلارف: أي عدد حصيح أو تعبري ينتجه ميكن اس تخدامه مكؤرش. ان حاولت قراءة أو كتابة عنرص غري موجود س تحصل عىل خطأ.IndexError ان اكنت قمية املؤرش سالبة س يكون العد عكس يا )من هناية القامئة(. كذكل فاملؤثر in يقوم بنفس العمل. >>> cheeses = ['Cheddar', 'Edam', 'Gouda'] >>> 'Edam' in cheeses True >>> 'Brie' in cheeses False for cheese in cheeses: print cheese 10.3 املرور عىل عنارص القامئة الطريقة الشائعة للمرور يه حلقة for و حنوها كنحوها يف انلارف: قد يكون هذا اكفيا ان كنت تريد قراءة عنارص القامئة فقط. أما لتحديث و كتابة العنارص فس تحتاج اىل املؤرشات و
الطريقة الشائعة لعمل هذا يه دمج range فكر بايثون 85 و :len for i in range(len(numbers)): numbers[i] = numbers[i] * 2 len متر هذه احللقة يف القامئة و حتدث لك عنرص فهيا. ترجع عدد عنارص القامئة range ترجع قامئة ابملؤرشات بدءا من املؤرش 0 اىل املؤرش 1-n حيث n يه طول القامئة. و يف لك دورة يف احللقة تأخذ i قمية املؤرش للعنرص التايل و عبارة التعيني يف منت احللقة تس تخدم i لقراءة اخر قمية للعنرص و تعني القمية اجلديدة. for x in []: print 'This never happens' حلقة for اليت ت س تخدم عىل قامئة فارغة ل ت نف ذ منت احللقة أبدا: عىل الرمغ من أنه للقامئة أن حتتوي عىل قامئة أخرى ال أن القامئة انلتواة تعترب عنرصا واحدا. طول هذه القامئة مثال هو 4: ['spam', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]] 10.4 العمليات عىل القوامئ املؤثر + يضم قامئتني: >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = a + b >>> print c [1, 2, 3, 4, 5, 6] و عىل نفس المنط املؤثر * يكرر القامئة عدد املرات املعطاة: >>> [0] * 4 [0, 0, 0, 0] >>> [1, 2, 3] * 3 [1, 2, 3, 1, 2, 3, 1, 2, 3] ]1, 2, املثال الاول يكرر ]0[ أربعة مرات و الثاين يكرر القامئة ]3 ثالثة. رشاحئ القامئة 10.5 مؤثر الترشحي ):( يعمل أيضا عىل القوامئ : >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> t[1:3] ['b', 'c'] >>> t[:4] ['a', 'b', 'c', 'd'] >>> t[3:] ['d', 'e', 'f'] ان أسقطت املؤرش الاول فان الرشحية ستبدأ عند البداية و ان أسقطت الثاين ستسمتر اىل هناية القامئة: >>> t[:] ['a', 'b', 'c', 'd', 'e', 'f']
و مبا أن القوامئ تتبدل مفن املفيد نسخ القامئة قبل القيام بأية معليات علهيا قد تعيد ترتيهبا. ان اكن مؤثر الترشحي عىل يسار التعيني س ميكنك من حتديث أكرث من عنرص: فكر بايثون 86 >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> t[1:3] = ['x', 'y'] >>> print t ['a', 'x', 'y', 'd', 'e', 'f'] 10.6 و طرق القوامئ يوفر ابيثون طرقا تعمل عىل القوامئ مثال append تضيف عنرصا جديدا للقامئة: >>> t = ['a', 'b', 'c'] >>> t.append('d') >>> print t ['a', 'b', 'c', 'd'] extend هذا املثال أبقى و تأخذ قامئة كقرينة و تضيف اكفة العنارص: >>> t1 = ['a', 'b', 'c'] >>> t2 = ['d', 'e'] >>> t1.extend(t2) >>> print t1 ['a', 'b', 'c', 'd', 'e'] t2 sort بدون تعديل. ترتب عنارص القامئة من الاسفل اىل الاعىل: طرق القوامئ لكها عقمية فهيي تعدل القامئة لكهنا ترجع اماكل. >>> t = ['d', 'c', 'e', 'b', 'a'] >>> t.sort() >>> print t ['a', 'b', 'c', 'd', 'e'] None ابخلطأ t.sort() t = فس تخيب النتيجة ان كتبت اخلرائط خط 10.7 الفلرتة و الاخزتال لتجمع لك أعداد قامئة ابماكنك كتابة حلقة كهذه: اس هت لت total ب 0 يف لك دورة يف احللقة تأخذ عبارة التعيني املزيدة هذه: مقابةل لهذه: def add_all(t): total = 0 for x in t: total += x return total x عنرصا من القامئة و الرمز =+ يوفر طريقا خمترصا لتحديث املتغري total += x total = total + x و بيامن يمت تنفيذ احللقة ت رامك total مجموع العنارص متغري ي س تخدم هبذا الشلك يدعى أحياان مرامك.accumulator
و جتميع عنارص القوامئ يشء شائع دلرجة أن ابيثون يوفر اقرتاان جاهزا هل : فكر بايثون 87 >>> t = [1, 2, 3] >>> sum(t) 6 sum و معلية من هذا النوع جتمع تسلسال من العنارص يف قمية واحدة تسمى أحياان اخزتال.reduce مترين 10.1 اكتب اقرتاان امسه العشية فهيا. nested_sum يأخذ قامئة عش ية من الاعداد الصحيحة و جيمع العنارص من اكفة القوامئ قد تود أحياان املرور عىل عنارص قامئة بيامن تبين أخرى. مثال الاقرتان التايل يأخذ قامئة من انلارف مث يرجع قامئة جديدة حروفها كبرية: اس هت معلية ك def capitalize_all(t): res = [] for s in t: res.append(scapitalize()) return res ف res اذن يه نوع أخر من املراكامت. لت res بقامئة فارغة و يف لك دورة يف احللقة نضيف العنرص التايل. تدعى أحياان اىل لك عنرص يف تسلسل. map capitalize_all )capitalize "ختط من" لهنا )و هو اقرتان يف هذه احلاةل الطريقة مترين 10.2 اس تخدم capitalize_all لكتابة اقرتان امسه.capitalize_nested يأخذ قامئة عش ية من انلارف و يرجع قامئة عشية جديدة لك احلروف هبا كبرية. معلية شائعة اخرى يه أن تأخذ بعض عنارص القامئة و تكون مهنا قامئة فرعية. مفثال الاقرتان التايل يأخذ قامئة من انلارف و يرجع قامئة حتتوي عىل احلروف الكبرية فقط: def only_upper(t): res = [] for s in t: if s.isupper(): res.append(s) return res isupper معلية مثل من طرق انلارف. و ترجع True only_upper ان اكنت السلسةل حتتوي عىل حروف كبرية فقط. تسمى فلرتة لهنا ختتار بعض العنارص و هتمل الاخرى. ميكن التعبري عن معظم معليات القوامئ املعروفة برتكيبة من الفلرتة و الاخزتال و مد اخلطوط. و لش يوعها يقدم لنا ابيثون خصائص لغوية دلمعها و من مضهنا الاقرتان map و رمز يسمى "انشاء القوامئ". مترين 10.3 اكتب اقرتان يأخذ قامئة من الارقام و يرجع مجعا ترامكيا أي أنه يرجع قامئة جديدة حيث العنرص رمق i يكون مجموع أول عنرصين 1+ i من القامئة الاصلية مثال امجلع الرتامكي ل ]3,1[,2 هو ]6,1[.,3
حذف العنارص 10.8 فكر بايثون 88 هناكل عدة وسائل حلذف عنارص من القامئة فان كنت تعرف مؤرش العنرص فباماكنك اس تخدام :pop >>> t = ['a', 'b', 'c'] >>> x = t.pop(1) >>> print t ['a', 'c'] >>> print x b تعدل pop القامئة و ترجع العنرص اذلي ح ذف و ان مل تزودها ابملؤرش س تحذف و ترجع أخر عنرص يف القامئة. و ان كنت ل حتتاج للعنرص انلذوف فباماكنك اس تخدام : del >>> t = ['a', 'b', 'c'] >>> del t[1] >>> print t ['a', 'c'] و ان كنت تعمل أي عنرص تريد حذفه لكن ليس املؤرش فباماكنك اس تخدام : remove القمية املرجعة من remove يه.None و حلذف أكرث من عنرص ميكنك اس تخدام del مع مؤرش للرشحية املراد حذفها: و اكلعادة فالرشحية ختتار مجيع القمي حىت و لكن ليس مع املؤرش الثاين. مترين 10.4 اكتب اقرتاان امسه الاخري مفثال: ترجع: اكتب اقرتاان امسه >>> t = ['a', 'b', 'c'] >>> t.remove('b') >>> print t ['a', 'c'] >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> del t[1:5] >>> print t ['a', 'f'] middle يأخذ قامئة و يرجع قامئة جديدة حتتوي عىل لك عنارص الاوىل ما عدا الاول و middle([1, 2, 3, 4]) [2, 3] chop يأخذ قامئة و يعدلها حبذف أول و أخر عنرص فهيا و يرجع.None انلارف القوامئ و 10.9 انلارف تسلسل من احلروف و القامئة تسلسل من القمي لكن قامئة احلروف و انلارف ليستا نفس اليشء. حمارف اىل قامئة من احلروف ابماكنك اس تخدام : list و لن list يه امس لقرتان جاهز للتحويل من >>> s = 'spam' >>> t = list(s) >>> print t ['s', 'p', 'a', 'm'] فيتوجب عليك جتنب اس تعاملها اكمس ملتغري و أان أيضا اجتنب اس تخدام l لهنا
تشبه 1 و لهذا اس تخدم t. فكر بايثون 89 الاقرتان list يقسم انلارف اىل حروف منفردة ان اردت تقسمي انلارف اىل لكامت فباماكنك اس تخدام : split و لهذه الطريقة قرينة اختيارية امسها delimiter )فاصل(. حتدد أي املثال التايل يس تخدم الرشطة ك : delimiter >>> s = 'pining for the fjords' >>> t = s.split() >>> print t ['pining', 'for', 'the', 'fjords'] من احلروف تريد اس تعاملها كحدود خارجية لللكمة. >>> s = 'spam-spam-spam' >>> delimiter = '-' >>> s.split(delimiter) ['spam', 'spam', 'spam'] join يه املقابل ل.split تأخذ قامئة من انلارف و تضيف عنارصها لبعض, و مبا أن join يه طريقة من طرق انلارف فيجب اس تدعاؤها عىل delimiter مث مترر القامئة كربمرت: اكن الفاصل يف هذه احلاةل هو حرف مسافة ف اس تخدم حمارف فارغة '' كفاصل. >>> t = ['pining', 'for', 'the', 'fjords'] >>> delimiter = ' ' >>> delimiter.join(t) 'pining for the fjords' join س تضع فراغات بني اللكامت. و لتضيف انلارف بدون مسافات 10.10 الاكئنات و القمي ان نفذان عبارات التعيني هذه: فنحن نعرف ان لك من يبيهنام الشلك 10.2. a = 'banana' b = 'banana' a و b يف احلاةل الاوىل تشري لك من a و b تشري اىل اكئن حمارف banana لكننا ل نعرف ان اكنتا نفس انلارف. هناك حالتان اىل اكئنني خمتلفني لكن هلام نفس القمية. و يف احلاةل الثانية تشريان اىل نفس الاكئن. a b 'banana' a b 'banana' 'banana' الشلك 10.2: رمس احلاةل. a [1, 2, 3] b [1, 2, 3] >>> a = 'banana' >>> b = 'banana' >>> a is b True الشلك 10.3 رمس احلاةل. لفحص ما اذا اكن متغريان يشريان اىل نفس الاكئن اس تخدم املؤثر : is
يف هذا املثال أوجد ابيثون اكئن حمارف واحد و أشار لك من a و و سيبدو رمس احلاةل كام يف الشلك b فكر بايثون 90 اليه لكن عندما تنشئ قامئتني فس تحصل عىل اكئنني: >>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> a is b False.10.3 يف هذه احلاةل نقول بأن القامئتني متساويتني لن دلهيام نفس العنارص الا أهنام ليس تا طبق الاصل لهنام ليس تا نفس الاكئن. ان تطابق اكئنان فس يكوان متساويني و العكس ليس ابلرضورة حصيح. حنن حىت الان نس تعمل لكمة "قمية" ماكن "اكئن" و العكس الا أن الدق هو القول أن للاكئن قمية. فان نفذت ]3, 1[ 2, س تحصل عىل اكئن قامئة قميته تسلسل من الاعداد الصحيحة. و ان اكن لسلسةل اخرى نفس العنارص نقول بأن لها نفس القمية و ل نقول نفس الاكئن. 10.11 ان اكتن تعدد املرجعية a تشري اىل اكئن ما مث عينت رمس احلاةل 10.4 يبني هذا الوضع. a اىل b س يكون لك من املتغريين مرجع الاكئن نفسه: >>> a = [1, 2, 3] >>> b = a >>> b is a True a b [1, 2, 3] الشلك 10.4: الرمس املستف <module> delete_head letters t list 0 1 2 'a' 'b' 'c' الشلك 10.5: الرمس املستف ربط الاكئن مبتغري يسمى مرجعية.reference يف هذا املثال هناك مرجعيتان لنفس الاكئن. الاكئن اذلي هل أكرث من مرجعية يكون هل أكرث من امس فنقول أن الاكئن متعدد املرجعيات.aliased و ان اكن الاكئن متعدد املرجعية غري ثبيت )يعد ل( فأي تغيري حتدثه مرجعية يؤثر يف الاخرى: >>> b[0] = 17 >>> print a [17, 2, 3] رمغ الفوائد اليت قد جتىن من هذا السلوك الا أنه خمبأ للخطاء. و يف العموم من المن جتنب تعدد املراجع عندما تعمل مع اكئنات متبدةل. تعدد املراجع ل يسبب املشالك عند العمل عىل الاكئنات الغري متبدةل يف هذا املثال: a = 'banana'
فكر بايثون 91 b = 'banana' لن يغري شيئا كون a و b مرجعان لنفس الاكئن أم ل 10.12 القوامئ كقرائن عندما مترر قامئة لقرتان حيصل الاقرتان عىل مرجع للقامئة و ان عدل الاقرتان برمرت يف القامئة فان املنادي سريى النتيجة مفثال delete_head حتذف العنرص الاول من القامئة: و هكذا تس تعمل: def delete_head(t): del t[0] >>> letters = ['a', 'b', 'c'] >>> delete_head(letters) >>> print letters ['b', 'c'] الربمرت t و املتغري letters الكهام مرجع لنفس الاكئن و الرمس املستف كام يف الشلك 10.5. من املهم التفريق بني العمليات اليت تعدل القوامئ و تكل اليت تنش هئا مفثال طريقة ينش هئا: append تعدل القامئة لكن املؤثر + >>> t1 = [1, 2] >>> t2 = t1.append(3) >>> print t1 [1, 2, 3] >>> print t2 None هذا الفرق همم عندما تكتب اقرتاانت املفرتض فهيا تعديل القوامئ مفثال الاقرتان التايل ل حيذف رأس القامئة: مؤثر الترشحي ينشئ قامئة جديدة و التعيني جيعل >>> t3 = t1 + [4] >>> print t3 [1, 2, 3, 4] def bad_delete_head(t): t = t[1:] # WRONG! t البديل لهذا هو كتابة اقرتان ينشئ و يرجع قامئة جديدة يرتك هذا الاقرتان القامئة الاصلية كام يه و هكذا يس تعمل: مرجعا لها لكن ليس لي من هذا تأثري عىل القامئة اليت مررت كقرينة. مفثال tail ترجع العنارص ما الاول يف قامئة ما: def tail(t): return t[1:] >>> letters = ['a', 'b', 'c'] >>> rest = tail(letters) >>> print rest ['b', 'c']
10.13.1 عالج الاخطاء فكر بايثون 92 عدم الا نتباه عند اس تعامل القوامئ )و غريها من الاكئنات املتبدةل( يؤدي عادة اىل انفاق الساعات يف البحث عن اسباب الخطاء. هنا بعض الخطاء الشائعة و طرق جتنهبا: ل تنس بأن غالبية طرق القوامئ تعدل القرائن و ترجع جديدة و ترتك الاصلية كام يه. و ان اعتدت كتابة نصوص برجمية للمحارف هكذا: فس تغريك كتابة نصوص للقوامئ هكذا: لن None و هذا عكس طرق انلارف اليت ترجع حمارف word = word.strip() t = t.sort() # WRONG! None ترجع sort فان العملية التالية اليت س تقوم هبا مع t س تفشل عىل الاغلب. قبل البدء ابس تعامل طرق و رموز القوامئ اقرأ واثئقها بمتعن مث اخترب معلها يف الوضع التفاعيل. الواثئق اليت ترشح الطرق و الرموز اليت تتشارك هبا القوامئ و التسلسالت الاخرى )اكنلارف( موجودة عىل:.http://docs.python.org/2/library/stdtypes.html#typesseq و الواثئق اليت ترشح الرموز و الطرق اليت ختتص هبا التسلسالت املتبدةل موجودة عىل:.http://docs.python.org/2/library/stdtypes.html#typesseq-mutable 2. اخرت لغة و ابق معها. من مشالك القوامئ يه كرثة الافاكر اليت متكنك من القيام ابلش ياء. مفثال حلذف عنرص من القامئة ميكنك اس تخدام.slice و حىت تعيني del أو remove أو pop و لضافة عنرص ميكنك اس تخدام append أو الرمز +. و افرتاضا أن t قامئة و x عنرص فهيا فالتايل حصيح: و التايل خطأ: t.append(x) t = t + [x] t.append([x]) t = t.append(x) t + [x] t = t + x # WRONG! # WRONG! # WRONG! # WRONG!.3 جرب لك من هذه الامثةل يف الوضع التفاعيل لتتأكد من أنك اس توعبت ما تفعهل. لحظ بأن الاخري فقط سيسبب خطأ أثناء التشغيل أما البايق فلن ترسل خطأ لكهنا لن تفعل املقصود مهنا. امعل نسخا لتجنب تعدد املراجع: ان اردت اس تخدام طرق ك معل نسخة: sort و اليت تعدل عىل القرائن لكنك حباجة لن حتتفظ ابلقامئة الاصلية أيضا ميكنك orig = t[:] t.sort() يف هذا املثال اكن ميكنك اس تخدام الاقرتان اجلاهز sorted و اذلي يرجع قامئة جديدة و مرتبة و يرتك الاصلية يف حالها الا أنه يف هذه احلاةل عليك جتنب اس تخدام sorted اكمس ملتغري.
فكر بايثون 93 املعاين 10.14 قامئة :list تسلسل من القمي. عنرص :element أحد القمي يف قامئة )أو أي تسلسل اخر( يسمى أيضا. item مؤرش :index قمية عدد حصيح تؤرش اىل عنرص يف القامئة. املرور عىل القامئة :list traversal الوص ول اىل لك عنرص يف القامئة ابلتوايل. خط اخلرائط :Mapping عالقة يرتبط هبا لك عنرص يف مجموعة مع عنرص يف مجموعة أخرى. مفثال القامئة يه ارتباط بني املؤرشات و العنارص. املرامك :accumulator متغري يس تخدم يف حلقة لتجميع )أو مرامكة( النتيجة. التعيني املزيد :augmented assignment عبارة حت دث قمية متغري ابس تخدام رمز حوسيب ك =+. اخزتال :reduce منط معليايت يمت فيه املرور عىل عنارص تسلسل مث مرامكهتا يف نتيجة وحيدة. خط :Map منط معليايت يمت فيه املرور عىل عنارص تسلسل و القيام بعملية ما عىل لك مهنا. الفلرتة :filter منط معليايت يمت فيه املرور عىل عنارص قامئة و انتقاء ما يفي برشوط ما مهنا. اكئن :object يشء ميكن ملتغري أن يكون مرجعا هل و للاكئن منط و قمية. مساوي :equivalent أن تكون لها نفس القمية. طبق الاصل :identical أن يكون نفس الاكئن ( و ابلتايل مساوي(. مرجع :reference الرابطة بني متغري و قمية. تعدد املرجعية : Aliasing ظرف يكون فيه متغريين أو كرث مرجعا لنفس الاكئن. انلدد : delimiter حرف أو حمارف تس تخدم لبيان املوقع اذلي سيمت تقسمي انلارف عنده. متارين 10.15 مترين 10.6: اكتب اقرتاان امسه is_sorted يأخذ قامئة كربمرت و يرجع True ان اكنت عنارصها مرتبة تنازليا و False ان اكنت غري ذكل. ابماكنك الافرتاض )كرشط مس بق( أنه ابلماكن مقارنة عنارص القامئة مبؤثرات النسبة <, <, اخل. مثال: is_sorted([1, 2, 3]) is_sorted([ 'b', 'a']) سرتجع True أما: سرتجع.False مترين 10.7 ان اكنت للكمتني نفس احلروف لكن خمتلفة الرتتيب يقال هلام anagram )جناس انقص (. اكتب اقرتاان و مسه is_anagram يأخذ حمارفتني و يرجع True ان اكنتا جناسا انقصا.
مترين 10.8 ما يسمى مفارقة اترخي امليالد:.1.2 ابماكنك القراءة عن هذه املسأةل عىل: فكر بايثون 94 اكتب اقرتاان امسه has_douplicates يأخذ قامئة و يرجع True ان ظهر أي عنرص أكرث من مرة و جيب أل تعدل عىل الاصل ان اكن هناك 23 طالبا يف صفك ما احامتل أن يكون اثنان منكام بنفس اترخي امليالد ابماكن توقع هذا الاحامتل ابنشاء عينة عشوائية ل 23 اترخي ميالد و حفص املتساوية مهنا تلميح: ميكنك انشاء توارخي ميالد عشوائية ابس تخدام اقرتان randint يف مديول random.http://en.wikipedia.org/wiki/birthday_paradox و ميكنك حتميل حيل للمسأةل من.http://thinkpython.com/code/birthday.py مترين 10.9 اكتب اقرتاان امسه remove_duplicates يأخذ قامئة و يرجع قامئة جديدة هبا العنارص الفريدة فقط من القامئة الاصلية. تلميح: ليس من الرضوري أن تكون بنفس الرتتيب مترين 10.10 اكتب اقرتاان يقرأ امللف words.txt مث ينشئ قامئة تكون فهيا لك لكمة عنرصا اكتب نسختني من هذا الاقرتان واحدة تس تعمل append و الثانية تس تعمل املزيدة[ 1 ] + t t = اهيام تأخذ وقتا أطول للتنفيذ ملاذا تلميح: اس تخدم مديول time لقياس اس هتالك الوقت. احلل:.http://thinkpython.com/code/wordlist.py مترين 10.11 لفحص ما اذا اكنت لكمة موجودة يف قامئة اللكامت قد تستعمل املؤثر in الا أنه يكون بطيئا لبحثه يف لك اللكامت ابلرتتيب. و لكون اللكامت مرتبة أجبداي سنمتكن من ترسيع العملية ابلبحث التنصيفي )يعرف أيضا ابلبجث الثنايئ "ابيرني"( و هو يشبه ما تقوم به عند البحث عن لكمة يف املعجم. ستبدأ يف املنتصف و ترى اذا ما اكنت لكمة البحث تس بق لكمة املنتصف هذه أو تلحقها فان اكنت تس بقها فستبدأ البحث يف منتصف النصف الاول و ترى أين تقع لكمة البحث منه و هكذا. و ااي اكن احلال فس تخترص نصف البحث يف لك مرة. ان اكن يف قامئة لكامت 113809 لكامت سيتطلب الامر 17 خطوة فقط لجياد لكمة البحث أو القول بعدم وجودها يف القامئة. اكتب اقرتاان و مسه حاةل عدم وجودها. bisect أو ميكنك قراءة واثئق الاقرتان اجلاهز يأخذ قامئة مرتبة و قمية مس هتدفة مث يرجع املؤرش لهذه القمية يف القامئة أو يرجع None يف bisect و اس تعامهل! احلل:.http://thinkpython.com/code/inlist.py مترين 10.12 تكون اللكمتان منعكستان ان اكنت احداهام معكوس حروف الاخرى. اكتب برانجما جيد لك الازواج املنعكسة يف قامئة اللكامت. احلل:.http://thinkpython.com/code/reverse_pair.py مترين 10.13 اللكمتان تتشاباكن ان أخذان حرفا من لك مهنام يف لك مرة لنكون يف الهناية لكمة جديدة مثال: shoe و cold تكوانن schooled احلل:.http://thinkpython.com/code/interlock.py
عرفان: اس تلهم هذا المترين من.http://puzzlers.org -1-2 فكر بايثون 95 اكتب برانجما جيد لك ازواج اللكامت املتشابكة يف قامئة اللكامت. تلميح: ل ترسد مجيع الازواج. هل ابماكنك اجياد اللكامت املتشابكة ثالثيا اي أن لك اثلث حرف هو ما يشلك اللكمة اجلديدة
فكر بايثون 96 الفصل احلادي عرش القواميس القاموس اكلقامئة الا أنه أمع. يف القامئة تكون املؤرشات أعداد حصيحة يف القاموس فميكن لها أن تكون من أي منط تقريبا. ميكنك الفكري ابلقاموس اكرتباط بني مجموعة من املؤرشات )و اليت تسمى مفاتيح( و مجموعة من القمي. فلك مفتاح يرتبط بقمية هذا التشارك بني املفاتيح و القمي يدعى زويج املفتاح-القمية key-value pair و أحياان عنرص.item و مكثال س ننشئ قاموسا يربط بني الاجنلزيية و الاس بانية فتكون القمي و املفاتيح مجيعها حمارف. الاقرتان اكمس ملتغري. dict ينشئ قاموسا جديدا بدون عنارص. و لن dict يه امس لقرتان جاهز فان عليك جتنب اس تخداهما متثل الاقواس املمتوجة {} قاموسا فارغا و لتضيف عنارص للقاموس ستس تخدم الاقواس املربعة: خيلق هذا السطر عنرصا يربط بني املفتاح و بيهنام نقطتان: >>> eng2sp = dict() >>> print eng2sp {} >>> eng2sp['one'] = 'uno' one و القمية uno صيغة اهلرجات يه أيضا صيغة الادخال فميكنك مثال انشاء قاموس جديد به ثالثة عنارص: املفتاح و ان طبعنا القاموس مرة اخرى سرنى زويج املفتاح-الفمية >>> print eng2sp {'one': 'uno'} >>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'} الا انك ستتفاجأ عند طباعة : enf2sp >>> print eng2sp {'one': 'uno', 'three': 'tres', 'two': 'dos'} فرتتيب أزواج القمي-املفاتيح ليس كام اكن م دخل بل حىت انك ان طبعت نفس املثال عىل حاسوبك س تحصل عىل نتيجة خمتلفة الواقع هو أن ترتيب العنارص يف القاموس غيبيا. الا أهنا ليست مشلكة لن العنارص يف القاموس ليست مؤرشة بأعداد حصيحة فبدل من ذكل ستستعمل املفاتيح للبحث عن القمي املقابةل لها: >>> print eng2sp['two'] 'dos' two يرتبط دامئا ابلقمية dos اذن فرتتيب العنارص ل هيم. ان اكن املفتاح ليس يف القاموس فس تحصل عىل اس تثناء: >>> print eng2sp['four']
فكر بايثون 97 يعمل الاقرتان len عىل القواميس فهو يرجع عدد أزواج املفاتيح-القمي KeyError: 'four' >>> len(eng2sp) 3 و املؤثر in يعمل أيضا عىل القواميس فهو يؤكد ان اكن شيئا يظهر مكفتاح يف القاموس )أن يظهر كقمية ليس جيدا كفاية(. >>> 'one' in eng2sp True >>> 'uno' in eng2sp False لرتى اذا ما اكن يشء يظهر كقمية يف القاموس ميكنك اس تخدام الطريقة values و اليت ترجع القمي عىل شلك قامئة مث بعد ذكل اس تعمل املؤثر :in >>> vals = eng2sp.values() >>> 'uno' in vals True يف القواميس يس تخدم املؤثر in لوغرمتية خمتلفة عن تكل اليت يس تخدهما يف القوامئ يف القوامئ يس تخدم لوغرمتية حبث search كام يف القسم 8.6 ذلكل عندما تتضخم القامئة يطول وقت البحث يف تناسب مبارش. يف القواميس يس تخدم ابيثون لوغرمتية تدعى جدول تقطيع hashtable لها خاصية ممزية و يه أنه همام بلغ عدد عنارص القاموس فان املؤثر in س يأخذ نفس الوقت تقريبا لن ارشح كيف ميكن ذكل لكن ميكنك القراءة عنه هنا:.http://en.wikipedia.org/wiki/Hash_table مترين 11.1 اكتب اقرتاان يقرأ لك لكامت words.txt و خيزهنا مكفاتيح يف قاموس ل هيم ما يه القمي مث ميكنك بعدها اس تخدام الرمز in كوسيةل رسيعة لفحص ما اذا اكنت حمارف ما موجودة يف القاموس. ان مقت ابلمترين 10.11 فباماكنك مقارنة رسعة العملية هنا مع الرسعة يف تطبيقها عىل القوامئ. 11.1 القواميس مكجموعة من العدادات افرض أن دليك حمارف و طلب منك معرفة عدد مرات ظهور لك حرف فهيا هناكل عدة وسائل حللها: 1- س توجد 26 متغريا واحدا للك حرف يف الاجبدية مث متر بعنارص السلسةل مث للك حرف متر به سزتيد قمية العداد املقابل هل و قد تس تخدم مرشوطة عشية. 2- قد توجد قامئة ب 26 عنرص مث س تحول لك حرف اىل رمق )ابس تخدام الاقرتان اجلاهز )ord مث ستس تخدم الرمق مكؤرش يف القامئة مث تزيد العداد املقابل. 3- قد تنشئ قاموسا تكون احلروف فيه املفاتيح و العدادات اكلقمي املقابةل و عندما تصادف احلرف لول مرة ستضيف عنرصا اىل القاموس و بعد ذكل تزيد قمية العنرص املوجود. لك من هذه اخليارات يقوم بنفس العملية احلوسبية الا أن لك مهنا يطبقها بشلك خمتلف. التطبيق هو طريقة للقيام ابلعمليات احلوسبية.implementation بعض التطبيقات أفضل من الاخرى مفثال من حماسن اس تخدام القواميس أنه ل يتطلب منا معرفة مس بقة بأي من احلروف س يظهر يف انلارف فقط علينا اجياد ماكن للحروف اليت س تظهر. النص الربجمي هل س يكون كهذا: def histogram(s):
فكر بايثون 98 امس الاقرتان اكن histogram ينشئ السطر الاول يف الاقرتان قاموسا فارغا و متر حلقة املتغري( موجودا يف القاموس سيخلق عنرصا جديدا مفتاحه و ان اكن احلرف c موجودا يف القاموس سزنيد.d[c[ هكذا يعمل الربانمج: d = dict() for c in s: if c not in d: d[c] = 1 else: d[c] += 1 return d املدرج التكراري و هو مصطلح احصايئ ملموعة من العدادات )أو الرتددات(. يف انلارف و يف لك دورة ان مل يكن احلرف c )امس و قميته الابتدائية 1 )مبا أننا قد رأينا هذا احلرف مرة واحدة( for >>> h = histogram('brontosaurus') >>> print h {'a': 1, 'b': 1, 'o': 2, 'n': 1, 's': 2, 'r': 2, 'u': 2, 't': 1} c املدرج التكراري يبني أن احلروف a و b ظهرت مرتني و هكذا. مترين 11.2 للقواميس طريقة امسها get تأخذ مفتاحا و قمية افرتاضية ان وجد املفتاح يف القاموس فان get سرتجع القمية املقابةل هل و الا سرتجع القمية الافرتاضية مثال: اس تخدم get لكتابة نسخة موجزة من histogram جيب أن تمتكن من الاس تغناء عن عبارة >>> h = histogram('a') >>> print h {'a': 1} >>> h.get('a', 0) 1 >>> h.get('b', 0) 0.if القواميس و التدوير 11.2 ان اس تخدمت قاموسا يف حلقة املقابةل هل: خمرجات هذا الاقرتان يه : for و مرة أخرى ليس للمفاتيح ترتيب حمدد. مترين فاهنا سمتر عىل مفاتيح القاموس. مثال print_hist تطبع لك مفتاح و القمية def print_hist(h): for c in h: print c, h[c] >>> h = histogram('parrot') >>> print_hist(h) a 1 p 1 r 2 t 1 o 1 11.3 للقواميس طريقة امسها keys ترجع مفاتيح القاموس و بدون ترتيب حمدد عىل شلك قامئة.
عدل print_hist ليطبع املفاتيح و القمي املقابةل لكن ابلرتتيب الاجبدي. فكر بايثون 99 البحث العكيس 11.3 ان اعطيت قاموسا امسه البحث.lookup d و مفتاح k س يكون من السهل عليك اجياد القمية املقابةل v = d[k] هذه العملية تدعى أما ان اعطيت القمية v و طلب اجياد املفتاح k فدليك مشلكتان: الاوىل أنه قد يكون هناك اكرث مفتاح يرتبط ابلقمية v و حسب التطبيق فقد تمتكن من التقاط قمية واحدة أو قد تضطر لنشاء قامئة حتتوي مجيع القمي. الثانية عدم وجود حنو بس يط للقيام ابلبحث العكيس فعليك البحث. هذا اقرتان يأخذ قمية و يرجع أول مفتاح يقرتن ابلقمية: def reverse_lookup(d, v): for k in d: if d[k] == v: return k raise ValueError.raise هذا الاقرتان ليس سوى مثال اخر عىل منط البحث ا ل اهنا تس تخدم مزية مل نرها من قبل تتسبب عبارة raise ابس تثناء هنا تس ببت ب ValueError و اذلي يعين يف الغالب وجود خطب ما يف قمية الربمرت. ان وصلنا اىل هناية احللقة فس يعين أن هاك مثال عىل حبث عكيس انحج: و حبث فاشل: v ل تظهر يف القاموس كقمية و عليه فسرنفع ( raise ) اس تثناءا. >>> h = histogram('parrot') >>> k = reverse_lookup(h, 2) >>> print k r >>> k = reverse_lookup(h, 3) Traceback (most recent call last): File "<stdin>", line 1, in? File "<stdin>", line 5, in reverse_lookup ValueError أن ترفع انت اس تثناءا أو أن يرفعه ابيثون فالنتيجة واحدة: س يطبع مالحقة و رساةل خطأ. تأخذ عبارة raise تفاصيل اخلطأ كقرينة اختيارية مفثال: >>> raise ValueError('value does not appear in the dictionary') Traceback (most recent call last): File "<stdin>", line 1, in? ValueError: value does not appear in the dictionary البحث العكيس ابطأ من البحث الامايم ذلكل س يعاين أداء حاسوبك ان مقت به بكرثة أو اكن جحم القاموس كبريا. مترين 11.4 عدل عىل توجد مفاتيح مرتبطة. reverse_lookup حبيث يبين و يرجع قامئة بلك املفاتيح اليت تقرتن ب v أو قامئة فارغة ان مل
11.4 القواميس و القوامئ فكر بايثون 100 ميكن للقوامئ أن تظهر كقمي يف القاموس مفثال ان اكن دليك قاموسا يربط احلروف ابلرتددات فقد تود أن تعكسه أي خلق قاموس يربط الرتددات ابحلروف و مبا أنه من املمكن وجود عدة حروف لنفس الرتدد فس تكون لك قمية يف القاموس املعكوس قامئة. هاك اقرتاان يعكس قاموس: def invert_dict(d): inverse = dict() for key in d: val = d[key] if val not in inverse: inverse[val] = [key] else: inverse[val]append(key) return inverse يف لك دورة يف احللقة تأخذ key مفتاحا من d و تأخذ val القمية املقابةل. و ان مل تكن val موجودة يف inverse س يعىن أننا مل نرها من قبل فننشئ عنرصا و نس هتهل ب singleton )قامئة حتتوى عىل عنرص وحيد(. و ال فقد رأينا هذه القمية من قبل فنضيف املفتاح املقابل اىل القامئة. هذا مثال: >>> hist = histogram('parrot') >>> print hist dict dict list hist 'a' 'p' 'r' 1 1 2 inv 1 0 1 2 'a' 'p' 't' 't' 1 3 'o' 'o' 1 2 0 'r' الشلك 11.1 رمس احلاةل الشلك 11.1 هو رمس حاةل يبني hist و املفتاح-القمية بداخهل. ان اكنت القمي اعداد حصيحة أو قمي العادة ارمس القوامئ خارجه فقط لبقاء الرمس بس يطا. {'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1} >>> inverse = invert_dict(hist) >>> print inverse {1: ['a', 'p', 't', 'o'], 2: ['r']} dict.inverse القاموس ممث ل بصندوق يكون المنط فوقه و زويج عامئة أو حمارف فأان ارمسها يف العادة داخل الصندوق لكنين يف ميكن للقوامئ أن تكون قامي يف قاموس كام يبني هذا املثال لكن ل ميكن لها أن تكون مفاتيح. و هذا ما س يحدث ان حاولت: >>> t = [1, 2, 3]
فكر بايثون 101 >>> d = dict() >>> d[t] = 'oops' Traceback (most recent call last): File "<stdin>", line 1, in? TypeError: list objects are unhashable ذكرت يف السابق بأن القواميس مطبقة ابس تخدام جدول تقطيعي مما يعين أن املفاتيح جيب ان تكون hashable تقطيعية. الهاش hash هو اقرتان يأخذ قمية من أي نوع و يرجع عددا حصيحا. تس تخدم القواميس هذه الاعداد و تسمى قمي التقطيع لتخزين ازواج املفاتيح-القمي و البحث فهيا. س يعمل هذا النظام جيدا لو اكنت املفاتيح غري متبدةل. لكن لو اكنت متبدةل اكلقوامئ س تحدث أمور غري محمودة مفثال عندما تنشئ أزواج مفاتيح-قمي فان ابيثون هييش املفتاح و خيزنه يف املوقع املقابل و ان عدلت املفتاح و هيش ته مرة اخرى س يذهب اىل موقع اخر. يف هذه احلاةل س يكون هناك مدخالن لنفس املفتاح أو قد ل تمتكن من العثور عىل املفتاح. و يف لكتا احلالتني لن يعمل القاموس بشلك حصيح. لهذا السبب اكن عىل املفاتيح و ليس عىل المناط املتبدةل أن تكون تقطيعية. أبسط طريقة للتحايل عىل هذا التقييد هو اس تعامل الصفوف tuples و هو ما سرناه يف الفصل التايل. مبا أن القوامئ و القواميس متبدةل فال ميكن اس تخداهما مكفاتيح لكن ميكن اس تخداهما كقمي. مترين 11.5 اقرأ واثئق طريقة القاموس set.default و اس تخدهما لكتابة نسخة موجزة من invert_dict احلل :.http://thinkpython.com/code/invert_dict.py املذكرات 11.5 ان كنت قد لعبت قليال بفبيوانيش من القسم 6.7 فقد تكون قد لحظت أنه لكام كربت القرينة اليت الوقت ليبدأ الاقرتان ابلعمل و أكرث من ذكل فقد ازداد زمن التشغيل أيضا. لكام طال تزودها fibonacci n 4 fibonacci n 3 fibonacci n 2 fibonacci fibonacci fibonacci fibonacci n 2 n 1 n 1 n 0 fibonacci fibonacci لتفهم السبب انظر اىل الشلك 11.2 اذلي يبني رمس النداء ل الشلك 11.2: رمس النداء. مع n=4 fabonacci يبني رمس النداء مجموعة من اطارات الاقرتاانت مع خطوط تصل لك اطار اىل الطار اذلي ينادي عليه. يف رأس الرمس اكنت fibonacci مع 4=n تنادي fibonacci مع 3=n و مع 2=n. و بدورها فان fabonacci مع 3=n تنادي fibonacci مع 2=n و 1=n و هكذا. ان عددت مك مرة نودي عىل n 1 n 0, و fibonacci(1) سرتى بأن هذا احلل ليس كفؤا للمسأةل و fibonacci(0)
سزيداد الوضع سوءا لكام كربت القرينة. فكر بايثون 102 متابعة القمي اليت اس تعملت و ختزيهنا يف قاموس هو أحد احللول. فالقمية اليت خزنت لس تعامل لحق تسمى مذك رة memo هذه نسخة مت ذك رة ل :fabonacci known = {0:0, 1:1} def fibonacci(n): if n in known: return known[n] res = fibonacci(n-1) + fibonacci(n-2) known[n] = res return res known هو قاموس يتابع و حيتفظ بأرقام فبوانيش اليت تعرفنا علهيا. يبدأ : 0 تصل ب 0 و 1 تصل ب 1. يف لك مرة ينادى fabonacci فانه يتحقق من املذكرة فان عليه أن حيسب قمية جديدة و يضيفها للقاموس مث يرجعها. مترين 11.6 شغل هذه النسخة من التشغيل. known fabonacci فان اكنت النتيجة مدونة هناك سريجع حال. و ال و كذكل النسخة الاصلية عىل نطاق من الربمرتات مث قارن زمن مترين 11.7 حول اقرتان أكرمان يف المترين 6.5 اىل اقرتان مبذكرة و انظر ان اكن هذا التحويل يسمح بتقيمي الاقرتان بقرائن أكرب تلميح: ل. احلل:.http://thinkpython.com/code/ackermann_memo.py 11.6 املتغريات العمومية يف املثال السابق و جدت known خارج الاقرتان لهذا فهيي تنمتي لطار خاص يسمى الرئييس. main تسمى املتغريات يف main أحياان معومية global لن الوصول الهيا ممكن من اي اقرتان. و عىل خالف املتغريات املوضعية اليت ختتفي مبجرد انهتاء اقرتاهنا من العمل فاملتغريات العمومية تسمتر يف الوجود من نداء لقرتان اىل أخر. من الشائع اس تخدام املتغريات العمومية للراايت flags و عبارة عن يه متغريات بوليان ترفع "علام" ان حتقق الرشط. مفثال تس تخدم بعض الربامج راية تسمى verbose للتحمك مبس توى تفاصيل اهلرجات: verbose = True def example1(): if verbose: print 'Running example1' و ان حاولت اعادة تعيني متغري معويم س تفاجأ ي فرتض يف املثال التايل أن يتحقق من اذا ما نودي عىل الاقرتان: def example2(): been_called = True # WRONG الا أنك عندما تشغهل سرتى بأن قمية been_called ل تتغري. املشلكة يه أن example2 خيلق متغريا موضعيا امسه been_called و املتغري املوضعي خيتفي ابنهتاء الاقرتان و ل يكون هل أثر عىل املتغري العمويم. عند التعيني ملتغري معويم داخل الاقرتان عليك الاعالن عن املتغري قبل استعامهل: been_called = False
فكر بايثون 103 و كن عبارة ختلق متغريا موضعيا." def example2(): global been_called been_called = True global هذا مثال حياول حتديث متغري معويم: و ان شغلته س تحصل عىل: تقول للمف رس: "يف هذا الاقرتان عندما أقول been_called فانين أعين املتغري العمويم ل count = 0 def example3(): count = count + 1 # WRONG UnboundLocalError: local variable 'count' referenced before assignment يفرتض ابيثون أن count موضعيا مما يعين أنك تقرأه قبل أن تكتبه. احلل و مرة اخرى هو اعالن count متغريا معوميا: ان اكن املتغري العمويم غري ثبيت فميكنك تعديهل دون الاعالن عنه: def example3(): global count count += 1 known = {0:0, 1:1} def example4(): known[2] = 1 اذن فباماكنك الاضافة و احلذف و استبدال عنارص القامئة العمومية او القاموس العمويم الا أنه عليك الاعالن عن متغري معويم ان أردت اعادة تعيينه: def example5(): global known known = dict() 11.7 الاعداد الصحيحة الطويةل ان مقت حبساب fabonacci(50) س تحصل عىل: تشري L يف هناية النتيجة اىل أن العدد الصحيح طويل أو أن المنط الصحيحة حىت الكبرية جدا مهنا لها نوع واحد.int جمال الاعداد الصحيحة ( المنط احلزي. >>> fibonacci(50) 12586269025L long يف ابيثون 3 اختفت long لك الاعداد ) حمدود و هذه الاعداد قد تصبح كبرية بشلك مبالغ فيه و منم ستسهكل الوقت و int تعمل املؤثرات احلسابية و كذكل اقرتاانت مديول مع int س يعمل مع.long math أيضا عىل الاعداد الصحيحة الطويةل ذلكل فأي اقرتان يعمل حفيامن تكون نتيجة العملية احلوسبية طويةل س يقوم ابيثون بتحويلها اىل عدد حصيح طويل )long( : >>> 1000 * 1000
فكر بايثون 104 اكنت النتيجة يف احلاةل الاوىل 1000000 >>> 100000 * 100000 10000000000L int و يف الثانية.long مترين 11.8 تعترب الاقرتاانت الاس ية للعداد الصحيحة الطويةل اساس لوغرمتيات ار اس ايه للتشفري بواسطة مفتاح عام اقرأ عن لوغرمتية RSA عىل:.http://en.wikipedia.org/wiki/RSA_(algorithm) مث اكتب اقرتاان يشفر و حيل تشفري الرسائل. عالج الاخطاء 11.8 لكام كرب جحم مجموعات البياانت أصبح التعامل مع عالج اخطاهئا عن طريق طباعهتا و حفصها يدواي أصعب. اليك بعض النصاحئ لعالج البياانت الضخمة: صغر جحم املدخالت: ان أمكنك فصغر جحم املدخالت. مثال ان اكن الربانمج يقرأ ملف نيص فابدأ بأول عرشة سطور أو بأصغر عينة جتدها ميكنك مثال تعديل امللفات نفسها أو )الافضل( تعديل الربانمج حبيث يقرأ أول n سطور. ان اكن هناك خطأ ميكنك انقاص n اىل احلد اذلي يظل فيه اخلطأ ظاهرا مث زدها تدرجييا لكام وجدت خطأ و حصحته. تفقد التلخيصات و الامناط: بدل من طباعة و حفص مجمل البياانت جرب طباعة تلخيصات البياانت: مثال عدد العنارص يف قاموس أو مجموع قامئة أرقام. خطأ شائع عند التشغيل يقع عندما تكون القمية من منط غري مناسب و لصطياد خطأ كهذا يكفي عادة طباعة منط القمية. اكتب حفصا ذاتيا: ابماكنك احياان كتابة نص برجمي يتفحص وجود الخطاء اليا. مثال ان كنت تكتب حوسبة لجياد املعدل لقامئة من الارقام فميكنك اضافة نص يتأكد من أن النتيجة ليست أكرب من أكرب عنرص يف القامئة أو أهنا ليست أصغر من أصغر عنرص فهيا يسمى هذا الفحص بفحص املعقولية check( )sanity لنه خيترب كل ان اكنت النتاجئ "معقوةل". نوع اخر من الفحوص يقارن نتيجة معليتني حوس بيتني و يقرر اذا ما اكنتا متسقتني و يسمى "حفص التناسق". الطباعة املهندمة للمخرجات: صياغة شلك خمرجات معلية صيد الخطاء يسهل اصطيادها. رأينا مثال يف القسم 6.9 مفديول pprint يزودان ابقرتان جاهز يظهر الامناط بشلك مقروء )انسانيا(. مرة أخرى الوقت اذلي تس تخدمه يف تركيب السق الت س يقلل الوقت اذلي تس تخدمه يف البحث عن أس باب الاخطاء. 11.9 قاموس املعاين : dictionary ختطيط بني مجموعة من املفاتيح و القمي املقابةل لها. زوج مفتاح-قمية :key-value pair متثيل للتخطيط بني مفتاح و قمية. عنرص :item امس اخر لزويج مفتاح-قمية. مفتاح :key اكئن يظهر يف القاموس اكلقسم الاول من زويج مفتاح-قمية. قمية :value اكئن يظهر يف القاموس اكجلزء الثاين من زويج مفتاح-قمية و عليك اعتبار هذا التعريف اكرث حتديدا من التعريف السابق للكمة قمية.
فكر بايثون 105 تطبيق :implementation أسلوب للقيام ابلعمليات احلوسبية. جداول التقطيع : hashtable لوغرمتية تس تخدهما قواميس ابيثون. اقرتان تقطيعي : hash function اقرتان تس تخدمه جداول التقطيع حلساب موقع املفتاح. تقطيعي : hashable منط هل وظيفة تقطيعية. الامناط الثبيتة اكلعداد الصحيحة و العامئة و انلارف تقطيعية. و الامناط املتعدةل اكلقوامئ و القواميس ليست تقطيعية. حبث :lookup معلية معجمية بأخذ مفتاح و العثور عىل القمية املقابةل هل. حبث عكيس :reverse lookup معلية معجمية بأخذ قمية و البحث عن مفتاح أو أكرث لها. وحيدة :singleton قامئة )أو اي تسلسل اخر( هبا عنرص وحيد. رمس النداء :call graph رمس يظهر لك اطار خلق خالل تنفيذ الربانمج يرمس فيه سهام من املنادي اىل املنادى. مدرج تكراري :histogram محموعة من العدادات. مذكرة : memo قمية حوس بة ت دون يف مذكرة لتجنب القيام ابحلوسبة ذاهتا مس تقبال. متغريات معومية :global variables متغري يعرف خارج الاقرتان ميكن الوصول للمتغريات العمومية من داخل أي اقرتان. راية :flag متغري بوليان يس تخدم لالشارة ان اكن الرشط.True اعالن :decliration عبارة ك global تبلغ املف رس شيئا يتعلق ابملتغري. متارين 11.11 مترين 10.9 ان كنت قد معلت عىل المترين 108 فس يكون دليك الاقرتان كربمرت و يرجع True ان ظهر أي اكئن أكرث من مرة فهيا. has_duplicates و اذلي يأخذ قامئة اس تخدم قاموسا لكتابة نسخة أرسع و أبسط من.has_duplicates احلل:.http://thinkpython.com/code/has_duplicates.py مترين 11.10 يقال للكمتني "تدوران" ان اكن تدوير احداهام يعطي الاخرى )أنظر rotate_word يف المترين 8.12( اكتب برانجما يقرأ قامئة لكامت و جيد لك الازواج اليت تدور احلل:.http://thinkpython.com/code/rotate_pairs.py مترين 11.11 هذه أجحية أخرى من Talk: Car "ارسلت هذه من قبل صديق امسه دان أولريي. فلقد صادف لفظة شائعة من مخسة حروف مؤخرا و اكنت لها اخلاصية الفريدة التالية ان حذفت حرفها الاول س تجعل البايق لفظة متجانسة لفظيا من اللكمة الاصلية أي لكمة تسمع كام تسمع اللكمة الاصلية مث ان أرجعت احلرف الاول و حذفت الثاين س تجعل اللكمة الناجتة متجانسة لفظيا أيضا مع الاصلية السؤال هو ما يه اللكمة الاصلية سأعطيك مثال ل يعمل أنظر اىل اللكمة امخلاس ية) wrack,w),r,a,c K و تعين حطام أو خراب ان حذفت احلرف الاول فسأحصل عىل RACK و تعين رف و أرجعت W مث حذفت R فس تحصل عىل WACK و يه لكمة ذات معىن الا أهنا ليست متجانسة لفظيا سابقاهتا.
فكر بايثون 106 الا أنه هناك ابلفعل لكمة واحدة عىل الاقل نعمل عهنا حنن و دان ان حذفت أي من حرفهيا الاولني تدل لكمة متجانسة لفظيا. السؤال ما يه اللكمة " ميكنك اس تخدام القاموس من متارين 11.1 لفحص اذا ما اكنت انلارف هذه موجودة يف قامئة اللكامت. للتأكد اذا ما اكنت لكمتان متجانس تان لفظيا ميكنك الاطالع عىل القاموس اللفظي.http://www.speech.cs.cmu.edu/cgi-bin/cmudict أو منhttp://thinkpython.com/code/c06d. و ميكنك حتميل CMU.http://thinkpython.com/code/pronounce.py read_dictionary الاسايس لها. و ميكن حتميهل من و به اقرتان امسه يقرأ القاموس اللفظي و يرجع قاموس ابيثون يربط بني لك لكمة و انلارف اليت تصف اللفظ اكتب برانجما يرسد مجيع اللكامت اليت تصلح حال لجحية.Car Talk احلل:.http://thinkpython.com/code/homophone.py
فكر بايثون 107
فكر بايثون 108 الفصل الثاين عرش التوبالت Tuples 12.1 و ثبيتة التوبالت التوبالت يه تسلسل من القمي. و ميكن للقمية أن تكون من أي منط و هذه القمي تكون مؤ رشة بأعداد حصيحة فهيي شبهية من هذه الناحية ابلقوامئ. أمه الفروق بيهنام هو أن التوبالت ل تتبدل. حنواي فالتوبالت قامئة تفصل بني قميها الفواصل: ابلماكن وضع التوبالت بني قوسني ال أنه ليس الزاميا: ليك تنشئ توبل عليك كتابة فاصةل يف هناية العبارة: القمية اليت توضع بني قوسني ل تعترب توبل: و طريقة أخرى لنشاء توبل يه الاقرتان اجلاهز >>> t = 'a', 'b', 'c', 'd', 'e' >>> t = ('a', 'b', 'c', 'd', 'e') >>> t1 = 'a', >>> type(t1) <type 'tuple'> >>> t2 = ('a') >>> type(t2) <type 'str'> tuple ان اس تخدمته بدون قرائن فانه س ينشئ توبل فارغة: ان اكنت قرينته تسلسال ما )قامئة حمارف أو توبل( فس تكون النتيجة توبال من عنارص ذكل التسلسل: و لكون tuple اسام لقرتان جاهز فيجب عليك جتنب اس تخدامه اكمس ملتغري. معظم مؤثرات القوامئ تعمل عىل التوبل فالقواس املربعة ستشري اىل العنرص: >>> t = tuple() >>> print t () >>> t = tuple('lupins') >>> print t ('l', 'u', 'p', 'i', 'n', 's') >>> t = ('a', 'b', 'c', 'd', 'e') >>> print t[0] 'a' املؤثر slice س يحدد نطاقا من عنارص التوبل: >>> print t[1:3]
فكر بايثون 109 الا أنك ان حاولت تعديل أحد عنارص التوبل فس تحصل عىل خطأ: ('b', 'c') >>> t[0] = 'A' TypeError: object doesn't support item assignment ل ميكنك التعديل عىل عنارص التوبل ال أنه ميكنك استبدال توبال بأخر: >>> t = ('A',) + t[1:] >>> print t ('A', 'b', 'c', 'd', 'e') للتوبل التعيني 12.2 غالبا ما نس تفيد من تبادل قمي متغريين و يف طرق التعيني التقليدية تضطر لستعامل متغري مؤقت فليك تبادل قمي a و البديل هو من العيار الثقيل فتعيينات التوبل أكرث أانقة: : b >>> temp = a >>> a = b >>> b = temp >>> a, b = b, a توبال من املتغريات يف القسم الايرس و يف الامين توبال من التعبريات. لك قمية تعني اىل املتغري املقابل لها و يمت تقيمي مجيع القمي اليت عىل اجلانب الامين قبل أي تعيني. جيب أن يكون عدد املتغريات عىل اجلانب الايرس مساو لعدد القمي عىل الامين: >>> a, b = 1, 2, 3 ValueError: too many values to unpack يف العموم ميكن للجانب الامين أن يكون أي منط من الامناط )حمارف قامئة أو توبل( مفثال ليك تفلق عنوان بريد الكرتوين اىل امس مس تخدم و نطاق )domain( قد تكتب: القمية املرجتعة من split تكون قامئة هبا عنرصين العنرص الول يعني ل >>> addr = 'monty@python.org' >>> uname, domain = addr.split('@') uname و الثاين يعني ل.domain >>> print uname monty >>> print domain pythonorg كقمي مرجعة الت وبل 12.3 حرفيا لالقرتان أن يرجع قمية واحدة فقط ال أنه ان اكنت القمية توبل فتأثريها يكون كرجاع عدة قمي. مفثال ان اردت تقسمي عددين حصيحني و أرجاع انجت القسمة و ابقهيا فلن يكون معليا أن حتسب x/y مث حتسب.x%y الافضل حساهبام مرة واحدة. يأخذ الاقرتان اجلاهز divmod قرينتني و يرجع توبل بقميتني الناجت و البايق و ميكنك حفظ النتيجة كتوبل: أو ميكنك اس تخدام تعيني لتوبل و ختزن العنارص بشلك مس تقل: >>> t = divmod(7, 3) >>> print t (2, 1) >>> quot, rem = divmod(7, 3)
فكر بايثون 110 هذا مثال لقرتان يرجع توبل: >>> print quot 2 >>> print rem 1 def min_max(t): return min(t), max(t) min_max max معا. min و اقرتاانن جاهزان جيدان أكرب و أصغر عنارص تسلسل أما فيحس هبام و يرجع توبال ابلقميتني 12.4 قرينة طول-املتغري variable-length argument بوسع الاقرتاانت أي عدد من القرائن و الربمرت اذلي يبدأ امسه ب يأخذ أي عدد من القرائن و يطبعها: لربمرت المل أن يأخذ أي امس يلممل * القرائن و جيعلها توبل مفثال printall def printall(*args): print args args املمكل للملمة هو التش تيت اس تخدام املؤثر *. مفثال: لن تعمل اكنت تقليدية. التايل يبني معل الاقرتان: >>> printall(1, 20, '3') (1, 20, '3').scatter أما ان شت ت التوبل فاهنا س تعمل: ان اكن دليك تسلسال من القمي و أردت متريرها اىل اقرتان كعدة قرائن فميكنك اليت تأخذ قرينتني ابلضبط يف التوبل: >>> t = (7, 3) >>> divmod(t) TypeError: divmod expected 2 arguments, got 1 >>> divmod(*t) (2, 1) و min هلام أن يأخذا أي عدد divmod مترين 12.1 تس تخدم العديد من الاقرتاانت اجلاهزة توبالت قرائن طول-املتغري. مفثال max من القرائن: الا أن >>> max(1,2,3) 3 sum اكتب اقرتاان امسه ل يفعل ذكل: >>> sum(1,2,3) TypeError: sum expected at most 2 arguments, got 3 sumall يأخذ أي عدد من القرائن و يرجع مجموعها. 12.5 القوامئ و التوبالت يأخذ الاقرتان اجلاهز zip تسلسلني أو أكرث و يضغطها يف قامئة أو توبل حبيث حيتوي لك توبل عىل عنرص واحد من لك تسلسل. يف ابيثون 3 يرجع zip تكرارا من التوبل لكن ملعظم الاهداف يترصف التكرار اكلقامئة. هذا املثال يضغط حمارف و قامئة:
فكر بايثون 111 >>> s = 'abc' >>> t = [0, 1, 2] >>> zip(s, t) [('a', 0), ('b', 1), ('c', 2)] و نتيجته قامئة من التوبل لك مهنا حيتوي عىل حرف من انلارف و العنرص املقابل هل من القامئة. ان مل تكن التسلسالت بنفس الطول س تكون النتيجة بطول أقرصها: و ميكنك اس تخدام تعيني توبل يف حلقة for للمرور يف قامئة من التوبل: يف لك دورة يف احللقة خيتار ابيثون التوبل التايل يف القامئة و يعني العنارص ل هو: ان مجعت بني الوقت مفثال و >>> zip('anne', 'Elk') [('A', 'E'), ('n', 'l'), ('n', 'k')] t = [('a', 0), ('b', 1), ('c', 2)] for letter, number in t: print number, letter.number letter انجت هذه احللقة 0 a 1 b 2 c for و zip has_match : t1[i]=t2[i] و تعيني توبل س تحصل عىل تركيبة لغوية مفيدة للمرور يف تسلسلني )أو أكرث( بنفس يأخذ تسلسلني t1 و t2 و يرجع True ان عرث عىل مؤرش حبيث تكون ان احتجت املرور عىل عنارص تسلسل و مؤرشاهتا ميكنك اس تخدام الاقرتان اجلاهز و مرة اخرى خمرجات هذه احللقة يه: def has_match(t1, t2): for x, y in zip(t1, t2): if x == y: return True return False enumerate : for index, element in enumerate('abc'): print index, element 0 a 1 b 2 c 12.6 القواميس و التوبالت للقواميس طريقة تدعى items ترجع قامئة من التوبل يكون لك توبل زويج مفتاح-قمية. و كام تتوقع من القواميس فالعنارص أأرجعت بدون ترتيب معني. يف ابيثون 3 فالتكرار يترصف اكلقامئة. و ان رست يف الاجتاه الاخر ستمتكن من اس تخدام قامئة توبل لس هتالل قاموس جديد: >>> d = {'a':0, 'b':1, 'c':2} >>> t = d.items() >>> print t [('a', 0), ('c', 2), ('b', 1)] items ترجع تكرارا و ملعظم الغاايت
فكر بايثون 112 و ان مجعت بني >>> t = [('a', 0), ('c', 2), ('b', 1)] >>> d = dict(t) >>> print d {'a': 0, 'c': 2, 'b': 1} dict و zip و من طرق القواميس الطريقة و امجلع بني و اهلرجات يه: مرة أخرى. س تكتشف طريقة موجزة لنشاء القواميس: >>> d = dict(zip('abc', range(3))) >>> print d {'a': 0, 'c': 2, 'b': 1} update items و تعيني توبل و for اليت تأخذ قامئة من التوبل و تضيفها كزويج مفتاح-قمية اىل القاموس املوجود. س ي ك ون صيغة مرور مبفاتيح و قمي القاموس: for key, val in d.items(): print val, key 0 a 2 c 1 b من الشائع اس تخدام التوبل مكفاتيح يف القواميس )السبب الرئييس هو عدم القدرة عىل استعامل القوامئ(. مفثال قد خيطط دليل هاتف بني الامس الاخري و الامس الاول كزوجني و بني رمق الهاتف فعىل افرتاض أننا عينا last, first و number فس ميكننا كتابة: التعبري املوجود بني قوسني هو توبل. ميكننا اس تخدام تعيني توبل للمرور هبذا القاموس. directory[last,first] = number tuple 0 1 'Cheese' 'John' الشلك 12.1: رمس احلاةل dict ('Cheese', 'John') ('Chapman', 'Graham') ('Idle', 'Eric') ('Gilliam', 'Terry') ('Jones', 'Terry') ('Palin', 'Michael') '08700 100 222' '08700 100 222' '08700 100 222' '08700 100 222' '08700 100 222' '08700 100 222' الشلك 12.2: رمس احلاةل for last, first in directory: print first, last, directory[last,first] first هذه احللقة متر ابملفاتيح يف last مث الامس و رمق الهاتف املقابل هل. و اليت يه عبارة عن توبل و تعني العنارص يف لك توبل اىل و dictionary
فكر بايثون 113 يعرب عن التوبل بطريقتني يف رمس احلاةل النسخة املفصةل تظهر املؤرشات و العنارص متاما كام تظهر يف القامئة مثال التوبل 'John') ('Cheese', س تظهر كام يف الشلك 12.1. أما يف الرسوم البيانية الضخمة مفن الفضل التخيل عن التفاصيل. مثال الرمس دلليل الهاتف يبدو كام يف الشلك 12.2. و هنا تظهر التوبل ابس تخدام حنو ابيثون اكخزتال تصويري. رمق الهاتف الظاهر يف الرمس هو رمق الشاكوى يف BBC ذلا رجاءا ل تس تخدمه. مقارنة التوبل 12.7 مؤثرات النسبة تعمل عىل توبل و التسلسالت الاخرى. يبدأ ابيثون مبقارنة أول عنرص من لك تسلسل فان اكنت متساوية فس ينتقل اىل العنارص التالية و هكذا حىت يعرث عىل عنارص متخالفة. العنارص اليت تيل ذكل التخالف هتمل )حىت و ان اكنت كبرية جدا(: >>> (0, 1, 2) < (0, 3, 4) True >>> (0, 1, 2000000) < (0, 3, 4) True اقرتان sort يعمل بنفس الطريقة فانه يف الاساس يرتب العنارص حسب أولها لكن يف حاةل العقد سريتهبا حسب العنرص الثاين و هكذا متنح هذه املزية نفسها اىل منط يقال هل DSU و هو ل: تزيني Decorate تسلسل ببناء قامئة توبل بواحد أو أكرث من املفاتيح اليت تسبق العنارص من التسلسل فرز Sort قامئة من التوبل و ازاةل الزينة Undecorate ابنزتاع العنارص املرتبة من التسلسل. مثال افرض ان دليك قامئة لكامت و تريد ترتيهبا من الاطول اىل الاقرص: احللقة الاوىل تنشئ قامئة من التوبالت يكون لك توبل مهنا اللكمة و يس بقها طولها. تقارن def sort_by_length(words): t = [] for word in words: t.append((len(word), word)) t.sort(reverse=true) res = [] for length, word in t: res.append(word) return res sort reverse = True أول عنرص length أول و تأخذ العنرص الثاين فقط لكرس الروابط. القرينة اللكمة املفتاحية تأمر sort أن يسمتر برتتيب تنازيل. احللقة الثانية متر يف قامئة التوبل و تنشئ قامئة من اللكامت مرتبة تنازليا. مترين 12.2 يف املثال السابق ك رست الروابط عن طريق مقارنة اللكامت فاللكامت املتساوية الطول ظهرت مرتبة ترتيبا أجبداي
فكر بايثون 114 معكوسا. قد تتطلب تطبيقات أخرى كرس الروابط عشوائيا. عدل هذا املثال حبيث تظهر اللكامت متساوية الطول مرتبة عشوائيا. تلميح: أنظر الاقرتان random يف مديول.random احلل:.http://thinkpython.com/code/unstable_sort.py.1.2.3 12.8 تسلسالت التسلسالت لقد ركزت عىل القوامئ و التوبل لكن تقريبا لك الامثةل يف هذا الفصل ستعمل مع قوامئ القوامئ توبل التوبل و توبل القوامئ من الافضل أحياان احلديث عن تسلسالت التسلسالت لتجنب رسد لك الرتكيبات املمكنة. ميكن اس تخدام أنواع التسلسالت اهلتلفة )انلارف القوامئ و التوبل( ابلتبادل يف معظم السياقات فلامذا و كيف ختتار أحدها دون الاخر و ليك نبدأ ابلوحض انلارف لهنا حمددة أكرث من ابيق التسلسالت حيث جيب أن تكون العنارص حروفا و يه تقريبا ثبيتة. فان اكن هدفك استبدال احلروف يف انلارف فالفضل اس تخدام قامئة من احلروف. القوامئ شائعة أكرث من التوبل لهنا تتبدل عىل الاغلب. ال أن هناك بضعة حالت قد جتعكل تفضل التوبل: يف بعض السياقات يكون من الابسط دلليا انشاء التوبل كام يف عبارة return و يف حالت أخرى قد تفضل القوامئ. ان اردت اس تخدام تسلسال مكفاتيح يف قاموس فعليك اس تخدام منط ثبيت اكنلارف أو التوبل. و ان كنت مترر تسلسال كقرينة اىل اقرتان س يكون من المن اس تخدام التوبل فاحامتل ظهور سلوك غري متوقع بسبب تعدد املرجعيات أقل. و لن التوبالت ثبيتة فليس لها طرق مثل اقرتاانت جاهزة sorted و العنارص برتتيب اخر. sort reversed و reverse اليت تعدل القوامئ املوجودة. الا أن ابيثون يوفر و اليت تأخذ أي تسلسل كربمرت و ترجع قامئة جديدة هبا نفس الخطاء عالج 12.9 القوامئ و القواميس و التوبل تعرف عامة ب.data structure يف هذا الفصل بدأان برؤية هيالك بياانت مركبة كقوامئ التوبل و قواميس مفاتيحها توبل و قميها قوامئ. هيالك البياانت املركبة مفيدة الا أهنا مرتع ملا أمسيه الخطاء الشلكية أعين عندما يكون لهيالك البياانت النوع أو احلجم أو الرتكيب اخلطأ فان كنت تتوقع مىن قامئة هبا عدد حصيح واحد و أعطيك عدد حصيح حبت قدمي )ليس يف قامئة( فلن تعمل. و للمساعدة يف عالج أخطاء كهذه كتبت مديول امسه structshape يأخذ أي نوع من هيالك البياانت كقرينة و يرجع حمارف تلخص شلك هيلك البياانت ميكنك حتميهل من:.http://thinkpython.com/code/structshape.py ها يه نتيجة قامئة بس يطة: >>> from structshape import structshape >>> t = [1,2,3] >>> print structshape(t) list of 3 int
لو اكن الربانمج فاخرا لكتب list of 3 ints لكن اكن أسهل يل و هذه قامئة قوامئ: فكر بايثون 115 أ ل اتعامل مع صيغ امجلع. ان مل تكن عنارص القامئة من نفس النوع س يجمعها structshape ابلرتتيب حسب المنط: و هذه قامئة من التوبل: و هذه قاموس به ثالثة عنارص ختطط الاعداد الصحيحة اىل حمارف: فان كنت تواجه صعوابت يف مالحقة هيالك بياانتك >>> t2 = [[1,2], [3,4], [5,6]] >>> print structshape(t2) list of 3 list of 2 int >>> t3 = [1, 2, 3, 40, '5', '6', [7], [8], 9] >>> print structshape(t3) list of (3 int, float, 2 str, 2 list of int, int) >>> s = 'abc' >>> lt = zip(t, s) >>> print structshape(lt) list of 3 tuple of (int, str) >>> d = dict(lt) >>> print structshape(d) dict of 3 int->str سيساعدك.structshape املعاين 12.10 توبل :Tuple تسلسل ثبيت من العنارص. تعيني لتوبل : Tuple assignemt تعيني يكون التسلسل فيه عىل الميني و متغريات توبل عىل اليسار يقمي اجلانب الامين مث تعني عنارصه للمتغريات عىل اجلانب الايرس. مللمة gather : معلية جتميع توبل قرينة طول- املتغري. تش تيت : scatter معامةل تسلسل كقامئة من القرائن. Decorate-Sort-Undecorate اختصار : DSU و انزتاع قسم من النتيجة. هيلك بياانت Data structure أي زين-رتب -أزل الزينة. قالب معليايت يمت فيه انشاء قامئة توبل ترتيهبا : جتمع لقمي ذات صةل تكون يف الغالب مرتبة يف قوامئ أو توبل أو قواميس... اخل. شلك )هيلك بياانت( structure) : shape (of a data تلخيص لمنط و جحم و تركيبة هيلك البياانت. متارين 12.11 مترين 12.3 اكتب اقرتاان امسه most_frequent يأخذ حمارف و يطبع حروفها تنازليا حسب جحم تكرارها. احصل عىل عينات لنصوص من عدة لغات و راقب تغري ترددات احلروف يف لك لغة قارن نتيجتك ابجلدول:.http://enwikipedia.org/wiki/Letter_frequencies احلل:.http://thinkpython.com/code/most_frequent.py
مترين تلميح: 12.4 مزيدا من اجلناس اللفظي :anagram.1 فكر بايثون 116 أكتب برانجما يقرأ قامئة لكامت من ملف )انظر القسم 91( مث يطبع لكمجموعات اللكامت اليت هبا جناس لفظي. هنا مثال ملا جيب أن يظهر عليه اهلرج: ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled'] ['retainers', 'ternaries'] ['generating', 'greatening'] ['resmelts', 'smelters', 'termless'] 2. عدل املثال السابق حبيث يطبع أكرب مجموعات اجلناس اللفظي أول مث يتبعها اثين أطول املموعات و هكذا. 3. يف لعبة احلروف املبعرثة. تكون bingo عندما تلعب لك احلروف السبعة اليت عىل الرف مع احلرف اذلي عىل اللوحة لتكون لكمة مثاني ة احلروف. أي مجموعة من مثانية حروف س متكنك من معل أكرب عدد Bingo ممكن.http://thinkpython.com/code/anagram_sets.py احلل:.there are seven مترين 12.5 تسمى اللكمتني اللتني ان غريت ماكن حرفني من أهيام تغري اللكمة اىل الثانية metathesis pair مثل converse و conserve اكتب برانجما جيد لك الازواج املطابقة لهذا املعىن يف القاموس. تلميح: ل ختترب لك زوج من اللكامت و ل ختترب لك الاحامتلت لتبديل ماكن حرفني يف لك لكمة احلل:.http://thinkpython.com/code/metathesis.py عرفان: هذا المترين مس تلهم من مثال يف.http://puzzlers.org مترين 12.6 مرة أخرى من أجحيات :Car Talk.http://www.cartalk.com/content/puzzlers ما يه أطول لكامت اللغة الاجنلزيية و اليت جيب أن تصلح كلكمة اجنلزيية لكام أزلت واحدا من حروفها يف لك مرة حس نا ابماكنك حذف احلروف من أي انحية تريد أو من وسط اللكمة لكن ل ميكنك اعادة ترتيب احلروف. و يف لك مرة حتذف حرفا س تواجه بلكمة اجنلزيية أخرى و يف الخر س تنهتيي اىل حرف واحد و عىل هذا احلرف أن يكون لكمة اجنلزيية مقبوةل -لكمة موجودة يف املعجم. أريد أن أعرف ما يه أطول لكمة اجنلزيية هبذا الشلك و ما عدد حروفها سأعطيك مثال متواضعا: Sprite ستبدأ ب sprite مث حتذف حرفا لعهل من ادلاخل فلنحذف r فس تتبقى لنا spite مث نأخذ مهنا e ليتبقى spit مث حنذف s فيتبقى pit مث it و يف الهناية I. اكتب برانجما يعرث عىل لك اللكامت اليت ينطبق علهيا هذا الرشط مث جد أطولها. التحدي يف هذا المترين أكرب من سابقيه ذلا اليك بعض النصاحئ: 1. قد تود كتابة اقرتان يأخذ لكمة و حيتسب لك اللكامت اليت تودل مهنا ابزاةل حرف واحد )تسمى اللكامت املنتجة children أبناء اللكمة(. 2. اجرتاراي ميكن اخزتال اللكمة ان أمكن اخزتال أطفالها و كحاةل قاعدة ابماكنك اعتبار أنه ميكن اخزتال انلارف الفارغة. 3. ل حتتوي قامئة اللكامت اليت محلهتا wordstxt عىل لكامت من حرف واحد قد يكون عليك اضافة I و a و انلارف الفارغة. 4. لتحسني أداء برانجمك قد تكون حباجة لس تخدام ال memo لتجعل الربانمج يذكرك ابللكامت القابةل لالخزتال. احلل:.http://thinkpython.com/code/reducible.py
فكر بايثون 117 الفصل الثالث عرش دراسة حاةل: اختيار هيالك البياانت اللكامت تكرار حتليل 13.1 اكلعادة عليك عىل الاقل حماوةل حل الامترين التالية قبل قراءة حيل لها. مترين 13.1 اكتب برانجما يقرأ ملفا مث احلروف اىل حروف صغرية. لكامت اىل سطوره يقس م و يعري املسافات البيضاء و التشكيل مث حيول مجيع تلميح: مديول string يوفر حمارف امسها whitespaces و اليت حتتوي عىل و كذكل punctuation اليت حتتوي عىل التشكيل. لرن ان اكن بوسعنا جعل ابيثون يشمت: و ابماكنك أخذ طرق انلارف strip, replace مترين 13.2 مق بزايرة مرشوع اليت حقوقها أصبحت عامة. الكتب بصيغة ملفات نصية. مترين space, tab, newline اخل >>> import string >>> print string.punctuation!"#$%&'()*+,-/:;<=>?@[\]^_`{ }~ و translate ابلعتبار. جوتنربج http://gutenberg.org و محل من هناك ما يروق كل من الكتب عدل برانجمك من المترين السابق ليقرأ الكتاب اذلي محلته ختطى املعلومات اليت يف ترويسة الكتاب و عاجل ابيق اللكامت كام يف السابق. بعد ذكل عدل الربانمج ليع د اجاميل لكامت الكتاب و عدد املرات اليت استعملت فهيا لك لكمة. اطبع عدد اللكامت اهلتلفة يف الكتاب. قارن بني كتب خمتلفة لكت اب خمتلفني يف أزمنة خمتلفة. أي من املؤلفني هل أكرب املام ابللفاظ )كتابه يشمل عدد أكرب من الالفاظ اهلتلفة(. 13.3 عدل عىل الربانمج الس بق ليطبع أكرث 20 لكمة مكررة يف الكتاب. مترين 13.4 عدل الربانمج السابق ليقرأ قامئة لكامت )أنظر القسم 9.1( مث يطبع لك لكامت الكتاب الغري موجودة يف قامئة اللكامت. مك عدد الخطاءاملطبعية مك عدد اللكامت الشائعة اليت جيب أن تورد يف قامئة اللكامت. و مك عدد اللكامت الغامضة
13.2 العداد العشوائية فكر بايثون 118 ان أأعطيت احلواسيب نفس املدخالت فس تنتج نفس اهلرجات يف لك مرة لهذا يقال لها حمتية. احلمتية يف الغالب صفة محمودة طاملا أننا نتوقع أن تنتج لنا نفس احلس بة النتيجة نفسها لكن يف بعض التطبيقات نريد للحاسوب أن يفاجئنا الالعاب مثال واحض لهذه التطبيقات لكن هناك أكرث. لقد تبني أن معل برانمج غري حمتي حقيقي ليس ابلمر السهل ال أن هناك س بل جلعهل يبدو غري حمتي عىل الاقل مهنا اس تخدام خوارزميات تودل تقليدا للعداد العشوائية رمغ أهنا ليست أعدادا عشوائية لكن مبجرد نظر الهيا سرتى أنه من املس تحيل التفريق بيهنا و بني العشوائية. مديول random مديول random random يودل هذه الاعداد العشوائية املقدلة )من الان سأدعوها الارقام العشوائية(. يرجع أرقاما عامة عشوائية بني 0.0 و 1.0 )من مضهنا 0.0 و لكن ليس 1.0( و يف لك مرة تنادي فهيا س تحصل عىل رمق يف سلسةل طويةل و لرت عينة شغل هذا الربانمج: import random for i in range(10): x = random.random() print x low و high )و قد يكون أحدهام(. الاقرتان randint يأخذ الربمرتين low و high و لتختار عنرصا من قامئة عشوائيا ابماكنك اس تخدام :choice و يوفر مديول بضعة توزيعات أخرى. مث يرجع عددا حصيحا بني >>> random.randint(5, 10) 5 >>> random.randint(5, 10) 9 >>> t = [1, 2, 3] >>> random.choice(t) 2 >>> random.choice(t) 3 random اقرتاانت لتوليد قمي عشوائية من توزيعات مس مترة ك Gaussian, exponential, gamma و مترين 13.5 اكتب اقرتاان امسه choose_from_hist يأخذ مدرج تكراري اكذلي رشح يف القسم 11.1 و يرجع قامي عشوائية من املدرج و تكون خمتارة ابحامتل يتناسب مع ترددها مثال لهذا املدرج التكراري: سريجع اقرتانك a ابحامتل 2/3 و >>> t = ['a', 'a', 'b'] >>> hist = histogram(t) >>> print hist {'a': 2, 'b': 1} b ابحامتل 1/3.
فكر بايثون 119 import string 13.3 مدرج تكراري لللكامت عليك انلاوةل مع الامترين السابقة قبل التقدم ابماكنك حتميل حلويل من:.http://thinkpython.com/code/analyze_book.py و س تحتاج أيضا اىل.http://thinkpython.com/code/emma.txt اليك برانجما يقرأ ملفا و ينشئ مدرجا تكراراي من لكامته: هذا الربانمج يقرأ def process_file(filename): hist = dict() fp = open(filename) for line in fp: process_line(line, hist) return hist def process_line(line, hist): line = linereplace('-', ' ') for word in line.split(): word=word.strip(string.punctuation + string.whitespace) word = wordlower() hist[word] = hist.get(word, 0) + 1 hist = process_file('emma.txt') emma.txt process_file يف اذلي حيتوي نص" امة" جلني اوسنت سطور امللف و ميررها واحد تلو الاخر اىل.process_line يدور التكراري hist مكرامك. و ي س تخدم املدرج يس تخدم process_line طريقة انلارف replace لستبدال الوصالت )-( بفراغات قبل اس تخدام split لتقسمي السطر اىل قامئة من انلارف. مث متر يف قامئة اللكامت و تس تخدم strip و lower لزاةل التشكيل و لتحويل لك احلروف اىل حروف صغرية )اكن تعبري "حتويل لك احلروف" لالختصار تذكر بأن انلارف ثبيتة فطرق ك strip و lower ترجع حمارف جديدة(. و أخريا حي دث process_line و لعد لكامت امللف ميكننا جتميع الرتددات يف املدرج التكراري: و عدد اللكامت اهلتلفة هو جمرد عدد لكامت امللف: و هنا نص برجمي يطبع النتاجئ: و النتاجئ: املدرج التكراري اما عن طريق انشاء عنرص جديد أو الزايدة عىل عنرص موجود. def total_words(hist): return sum(hist.values()) def different_words(hist): return len(hist) print 'Total number of words:', total_words(hist) print 'Number of different words:', different_words(hist)
فكر بايثون 120 Total number of words: 161080 Number of different words: 7214 أكرث اللكامت 13.4 ورودا لنجد أكرث اللكامت اس تخداما ميكننا تطبيق ال DSU تأخذ اللكمة-ترددها و تكون مرتبة عكسيا حسب الرتدد: و هذه حلقة تطبع أكرث عرش لكامت ورودا: و هذه النتاجئ من نص "امة" : most_common مدرجا تكراراي و ترجع قامئة توبل من def most_common(hist): t = [] for key, value in hist.items(): t.append((value, key)) t.sort(reverse=true) return t t = most_common(hist) print 'The most common words are:' for freq, word in t[0:10]: print word, '\t', freq The most common words are: to 5242 the 5205 and 4897 of 4295 i 3191 a 3130 it 2529 her 2483 was 2400 she 2364 13.5 الربمرتات الاختيارية لقد رأينا اقرتاانت تأخذ أعدادا خمتلفة من القرائن. من املمكن كتابة اقرتاانت يعرفها املس تخدم )user-defined( و تكون قرائهنا اختيارية كذكل. مفثال هذا الاقرتان يطبع أكرث اللكامت اس تخداما يف مدرج تكراري: الربمرت الول أسايس بيامن الثاين اختياري و القمية الافرتاضية ل num يه 10. و ان زودته بقرينة واحدة: فس تأخذ def print_most_common(hist, num=10): t = most_common(hist) print 'The most common words are:' for freq, word in t[:num]: print_most_common(hist) print word, '\t', freq num القمية الافرتاضية و ان زودته ابلقميتني:
فكر بايثون 121 فس تأخذ print_most_common(hist, 20) num قمية القرينة. بلكامت أخرى فالقرينة الاختيارية تقدم عىل الافرتاضية. ان اكن الاقرتان يأخذ برمرتات اختيارية و اخرى مطلوبة فس يقدم املطلوبة عىل الاختيارية مث تتبعها الاختيارية. 13.6 معليات الطرح يف القواميس مسأةل العثور يف القاموس عىل لكامت ل توجد يف word.txt قد تذكرك ابملموعات املمكةل أي أننا نريد معرفة لك اللكامت املوجودة يف مجموعة ما )و يه اليت يف الكتاب( و غري املوجودة يف مجموعة أخرى )و يه اللكامت اليت يف القامئة(. {1, 2, 3} \ {2, 3, 4} = {1} تأخذ subtract القاموسني d1 و d2 و ترجع قاموسا جديدا حيتوي عىل لك املفاتيح املوجودة يف d1 و لكن ليست موجودة يف d2 و طاملا أننا ل نكرتث لقميها فس نجعلها لكها nnone و لنجد اللكامت اليت يف الكتاب و ل توجد يف تكراري ل words.txt مث نطرح: اليك بعض النتاجئ من "امة": def subtract(d1, d2): res = dict() for key in d1: if key not in d2: res[key] = None return res process_file words.txt بوسعنا اس تخدام لبناء مدرج words = process_file('words.txt') diff = subtract(hist, words) print "The words in the book that aren't in the word list are:" for word in diff.keys(): print word, The words in the book that aren't in the word list are: rencontre jane's blanche woodhouses disingenuousness friend's venice apartment... set مترين 13.6 يوفر لنا ابيثون هيلك بياانت يسمى و به العديد من معليات املموعات املعروفة. اقرأ واثئقه عىل.http://docspython.org/2/library/stdtypes.html#types-set مث اكتب برانجما يس تخدم طرح املموعات للعثور عىل لكامت الكتاب الغري موجودة يف قامئة اللكامت احلل:.http://thinkpython.com/code/analyze_book2.py اللكامت 13.7 العشوائية ابسط خوارزمية لختيار لكمة من مدرج تكراري عشوائيا يه بناء قامئة هبا نسخ متعددة لنفس اللكمة عدد النسخ يتناسب مع تردد ورودها حسب املدرج التكراري و بعدها ختتار من هذه القامئة:
فكر بايثون 122 التعبري شبهية ب يوجد قامئة من نسخ انلارف ما عدا أن القرائن يه تسلسالت. def random_word(h): t = [] for word, freq in h.items(): text.end([word] * freq) return random.choice(t) extend.freq word [word] * freq append عددها أما الطريقة فهيي مترين 13.7 قامت اخلوارزمية السابقة بعملها لكن من الواحض عدم فعاليهتا: فلك مرة ختتار فهيا لكمة عشوائية س تعيد بناء القامئة و اليت يه حبجم الكتاب. من الواحض أن حتسيهنا يمكن يف بناء القامئة مرة واحدة مث القيام ابختيارات متعددة لكن القامئة ستبقى كبرية. البدائل: 1. اس تخدم keys فس يكون دليك قامئة بلكامت الكتاب. 2. انشئ قامئة حتتوي مجموع تردد اللكامت )انظر المترين (. 10.3 أخر عنرص يف هذه القامئة هو مجموع أعداد اللكامت يف الكتاب n. 3. اخرت رمقا عشوائيا بني 1 و n و اس تخدم تنصيف البحث )أنظر مترين 11.10( لتجد املؤرش حيث س يغرز الرمق العشوايئ يف املموع الرتامكي. 4. اس تخدم املؤرش لتجد اللكمة املقايةل يف القامئة. اكتب برانجما يس تعمل هذه اخلوارزمية لختيار لكمة عشوائية من الكتاب احلل:.http://thinkpython.com/code/analyze_book3.py حتليل ماركوف 13.8 ان اخرتت اللكامت عشوائيا من كتاب ف ل ما س تحصل عليه هو بعض الالفاظ أما مجةل حصيحة فال: this the small regard harriet which knightley's it most things "هذا القليل نس بة هارييت اليت للفروس ية فتكل أكرث أش ياء" اسرتسال اللكامت العشوائية اندرا ما يعقل فال توجد عالقة منطقية بني اللكامت املتعاقبة مفثال ستتوقع بعد الفعل فاعل أو امس فاعل و لن تتوقع "هل". لقياس عالقات كهذه هناك حتليل ماركوف اذلي يصف العالقة بني اللكمة و اليت تلهيا مثال أغنية :Eric, the half a bee Half a bee, philosophically, Must, ipso facto, half not be But half the bee has got to be Vis a vis, its entity D you see? But can a bee be said to be Or not to be an entire bee When half the bee is not a bee
فكر بايثون 123 Due to some ancient injury? و تعين )ابلعربية(: نصف حنةل فلسفيا هو يف احلقيقة نصف ل يكون. لكن عىل نصف النحةل أن يكون وهجا لوجه كياهنا. أفرتى لكن هل لنحةل قيل أهنا اكنت أو ل تكون ابلاكمل حنةل مل ا اكن نصف حنةل ليس حنةل رمبا جلرح قدمي يف هذا النص أأتبعت half the ابللكمة bee دامئا لكن العبارة the bee أتبعت أحياان ب has و أخرى ب.is اكنت نتيجة حتليل ماركوف يه الوصل بني البادئات ك half the و the bee و بني الالحقات ك has و.is ان أأعطيت هذه التخطيط فس ميكنك انتاج نص عشوايئ ان ابتدأت بأي ابدئة مث اخرتت عشوائيا أي لحقة حممتةل و بعدها ميكنك تركيب هناية البادئة مع الالحقة اجلديدة خللق ابدئة جديدة مث تعيد الك رة. مثال: ان ابتدأت ببادئة Half a فاللكمة التالية جيب أن تكون bee لن البادئة تظهر مرة واحدة يف النص و البادئة التالية س تكون a bee و عليه فس تكون الالحقة التالية اما phylosophically أو be أو.due اكن طول البادئة يف هذا املثال 2 دامئا الا أنه ميكنك معل حتليل ماركوف بأي طول لبادئة يسمى طول البادئة "ترتيب التحليل." مترين 13.8 حتليل ماركوف 1.اكتب برانجما يقرأ النص من ملف و جيرى حتليل ماركوف عليه عىل النتيجة أن تكون قاموسا يصل بني البوادئ و بني اللواحق انلمتةل للمجموعة أن تكون قامئة أو توبل أو قاموس الامر راجع كل لتقوم بأنسب الاختيارات. ميكنك اختبار برانجمك ابلطول 2 للبادئة لكن عليك كتابة الربانمج بطريقة جتعل اختبار أطوال اخرى ممكنا. 2.اضف اقرتاان للربانمج السابق لتودل نصا عشوائيا بناءا عىل حتليل ماركوف. خذ مثال من "امة" بطول البادئة :2 He was very clever, be it sweetness or be angry, ashamed or only amused, at such a stroke. She had never thought of Hannah till you were never meant for me?" "Icannot make speeches, Emma:" he soon cut it all himself. يف هذا املثال تركت اشارات الوصل موجودة عىل اللكامت النحو يف النتيجة اكن حصيحا لكن ليس جدا. دللية النص املنتج مقبوةل لكن ليس جدا. ما اذلي س يحدث ان زدت طول البادئة هل سيصبح النص
فكر بايثون 124 العشوايئ معقول أكرث 3.بعد أن يصبح برانجمك شغال قد تود جتربة اخللطات: ان حل لت نصوصا من كتابني اضافيني فستتودل نصوص بتوليفة من الالفاظ و الصيغ من هذه املصادر بشلك مسل. عرفان: دراسة احلاةل هذه مبنية عىل مثال من املامرسة الربجمية لكرجنان و ابيك. عليك انلاوةل يف هذا المترين قبل امليض قدما و بعدها ميكنك حتميل حيل هل:.http://thinkpython.com/code/markov.py سوف حتتاج أيضا اىل.http://thinkpython.com/code/emma.txt هيلكة بياانت 13.9 من املسيل اس تخدام حتليل ماركوف لنشاء نصوص عشوائية لكن هناك هدف لهذا المترين: هيلكة البياانت. يف س ياق حكل للامترين السابقة اكن عليك اختيار: كيف متثل البوادئ. كيف متثل مجموعات اللواحق انلمتةل. كيف متثل التخطيط من لك ابدئة اىل مجموعة اللواحق انلمتةل. اخليار الاخري سهل فمنط التخطيط الوحيد اذلي رأيناه هو القاموس فاكن اخليار الطبيعي. أما ابلنس بة للبوادئ فاخليار املنطقي اكن انلارف أو توبل انلارف. لكن للواحق هناك خياران أحدهام القامئة و الثاين الرتدد املعياري )قاموس(. كيف ختتار عليك أول التفكري ابلعلميات اليت س تحتاج اىل تطبيقها عىل لك هيلك بياانت. فللبوادئ تلزمنا القابلية حلذف لكمة من البداية و اضافهتا للهناية مثال ان اكنت البادئة احلالية يه Half a و اللكمة التالية يه bee يلزم أن تكون قادرا عىل حذف البادئة التالية a. bee قد يكون اخليار الاول قامئة لسهوةل اضافة و حذف العنارص لكننا حنتاج أيضا اىل القدرة عىل اس تخدام البوادئ مكفاتيح يف قاموس اذن مل تعد القوامئ خيارا مناسبا. مع التوبل ل ميكنك الاضافة أو احلذف لكن ابس تخدام رمز امجلع تس تطيع انشاء توبل جديد: تأخذ shift توبل من اللكامت الاوىل و مضاف اىل def shift(prefix, word): return prefix[1:] + (word,) prefix و حمارف word هنايته.word و تكون توبل جديد به لك اللكامت يف prefix ما عدا العلميات املطلوبة عىل مجموعات اللواحق تتضمن اضافة لحقة جديدة )أو زايدة تردد لحقة موجودة( مث اختيار لحقة عشوائية. اضافة لحقة جديدة سهل يف تطبيق الرتدد املعياري و سهل يف تطبيق القوامئ اختيار عنرص عشوايئ يف قامئة سهل الاختيار بكفاءة من تردد معياري أصعب )أنظر مترين 13.7(. حىت اللحظة حنن نتلكم عن السهوةل يف التطبيق لكن هناك عوامل أخرى جيب أن تؤخذ يف الاعتبار لختيار هيلك
فكر بايثون 125 بياانت مهنا زمن التشغيل. أحياان يكون هناك سبب نظري للتوقع بأن هيلك بياانت ما أرسع من غريه. مثال قلت سابقا أن املؤثر in أرسع يف القواميس منه يف القوامئ عىل الاقل عندما يكون عدد العنارص كبريا. الا أنك يف الغالب لن تعرف مس بقا أي التطبيقات س يكون ارسع. أحد احللول هو تطبيق الك اخليارين و رؤية أهيام أفضل يسمى هذا املنحى ب benchmark أو مقياس الداء أما البديل العميل فهو اختيار هيلك البياانت اذلي يكون حتقيقه أسهل مث ترى ان اكن رسيعا كفاية ابلنس بة للتطبيق املقصود ان اكن كذكل فال داعي لالس مترار و ال فهناك أدوات مثل مديول profile اذلي يظهر املواقع املس هتلكة للوقت يف الربانمج. العامل الاخر اذلي جيب أخذه ابلعتبار هو جحم التخزين فاس تخدام مدرج تكراري ملموعات اللواحق مثال س يحتل مساحة أصغر لنك س تخزن لك لكمة مرة واحدة فقط بغض النظر عن عدد مرات ظهورها يف النص. يف بعض احلالت جيعل توفري املساحة برانجمك أرسع و يف أقىص حالت استنفاذ اذلاكرة قد ل يعمل برانجمك ابملرة. لكن يف معظم التطبيقات يكون جحم التخزين اعتبارا اثنواي بعد رسعة التشغيل. و خاطرة أخرية: طوال هذه املناقشة كنت أحتدث عن اس تخدام هيلك بياانت واحد للتحليل و النشاء لكن طاملا أن هااتن مرحلتان منفصلتان فميكننا أيضا اس تخدام هيلك بياانت للتحليل و حنو ل الخر لالنشاء. س يكون هذا رحبا صافيا ان اكن الوقت املوفر خالل الانشاء أكرب من الوقت املستنفذ يف التحويل. الخطاء عالج 13.10 هناكل أربعة أش ياء ميكنك جتربهتا عندما حتاول عالج بقة رشسة: القراءة: تفحص نصك الربجمي و تأكد أنه يقول ما قصدت قوهل. التشغيل: اختربه بأن تقوم بتغيريات و بأن تشغل عدة نسخ. غالبا ما تت ضح املشلكة عندما تعرض اليشء الصحيح يف املاكن الصحيح. لكن يف أحيان أخرى قد يتطلب الامر منك اس هتالك بعض الوقت يف بناء السقالت. اعادة التفكري: خذ بعض الوقت لتفكر! أي نوع من الخطاء هو حنوي دليل أم خطأ عند التشغيل ما يه املعلومات اليت تس تقهيا من رساةل وجود اخلطأ أو من خمرجات الربانمج أي نوع من الخطاء ينتج املشلكة اليت بني يديك ما هو اخر يشء عدلته قبل ظهور املشلكة الرتاجع: يف بعض املواقف تكون احلمكة يه الرتاجع اعادة التعديالت الاخرية اىل وضعها السابق واحدة تلو الاخرى اىل أن خيتفي اخلطأ و تعود اىل الربانمج اذلي كنت تفهمه. مث ابدأ البناء من تكل النقطة. يعلق مبتديئ الربجمة أحياان يف واحدة من هذه النشاطات و ينسون النشاطات الاخرى. لك نشاط مهنا يأيت و معه منط فشهل. مثال قراءة برانجمك ستساعد ان اكن اخلطأ مطبعيا لكن ليس اذا اكن اخلطأ عدم فهم املبدأ. فان مل تفهم ما يقوم به برانجمك فلن تر اخلطأ و لو قرأته 100 مرة لن اخلطأ يف رأسك. اجراء التجارب قد يساعد خصوصا ان ج برت حفوصا صغرية و بس يطة. لكن اجراءها بدون قراءة النص أو التفكري فيه س يوقعك فامي أمسيه "برجمة امليش عىل غري هدى" و يه معلية القيام بتغيريات عشوائية اىل أن يقوم الربانمج ابلعمل الصحيح. ل داعي للتذكري بأن بأن الربجمة عىل غري هدى ستتطلب الكثري من الوقت. عليك انفاق الوقت يف التفكري. عالج الخطاء اكلعلوم التجريبية. فيجب أن يكون دليك فرضية واحدة عىل الاقل عن ماهية املشلكة ان اكنت دليك أكرث من فرضية ففكر ابختبار حيذف احداها.
فكر بايثون 126 أخ ذ اسرتاحة يساعد يف التفكري. و كذكل احلديث ان رشحت املشلكة اىل أحدمه )قد تكون أنت( فأحياان س تجد احلل حىت قبل اهناء الرشح. ان كرثت الخطاء يف الربانمج فلن تساعدك حىت أعىت طرق عالج الاخطاء و كذكل ان اكن النص كبري جدا و معقدا جدا. أحياان اخلطو اىل اخللف يكون حال ب سط الربانمج اىل احلد اذلي يعمل فيه بشلك حصيح و تفهمه. يرتدد مبتديئ الربجمة يف الرتاجع لعدم قبوهلم حذف سطرا من نص برجمي اكنوا قد كتبوه. اذا اكن نسخ الربانمج اىل ملف جديد يواس يك فقم بذكل و ابدأ بتعريته. ميكنك بعدها لصق قطع الربانمج واحدة تلو الاخرى. يتطلب العثور عىل بقة عتية منك القراءة و التشغيل و اعادة التفكري و أحياان الرتاجع. فان علقت يف احدى هذه النشاطات اتركها و جرب الاخرايت. 13.11 حمتي املعاين :deterministic الربانمج اذلي يقوم بنفس اليشء لكام شغ ل ان أعطي نفس املدخالت. الارقام العشوائية املزيفة :pseudorandom ذكل التسلسل من الارقام اذلي يبدو عشوائيا الا أنه وجد عن طريق برانمج حمتي. القمية الافرتاضية :default value يه القمية اليت تعطى لربمرت اختياري ان مل يزو د بقرينة. قياس الداء : Benchmarking معلية الاختيار بني هيالك البياانت عن طريق حتقيق بدائل مث حفصها عىل عينة من املدخالت انلمتةل. متارين 13.12 مترين 13.9 مزنةل اللكمة rank هو موقعها يف قامئة من اللكامت املرتبة حسب الرتدد: فأكرث اللكامت ترددا لها املزنةل 1 و اثين أكرث اللكامت ترتددا لها املنصب 2... اخل. قانون زف يصف العالقة بني مزنةل و تردد اللكامت يف اللغات الطبيعية.http://en.wikipedia.org/wiki/Zipf's_law حتديدا فهو يتوقع أن يكون الرتدد f لللكمة اليت منصهبا r هو: f = cr -s حيث s و c يه برمرتات تعمتد عىل اللغة و عىل النص ان أخذت خوارزمية الك جانيب املعادةل س تحصل عىل: logf = logc - s logr فان رمست منحىن log f و log r س تحصل عىل خط مس تقمي هل ميل s- و يتقاطع مع.log c اكتب برانجما يقرأ النص من ملف مث يعد الرتددات و يطبع سطرا للك لكمة برتتيب تنازيل يكون فيه log f و.log r اس تخدم برانمج الرسوم البيانية اذلي تفضل لرمس النتيجة مث انظر ان اكنت تشلك خطا مس تقامي. هل ميكنك توقع قمية s احلل:.http://thinkpython.com/code/zipf.Py و لرمس املنحىن قد حتتاج اىل تنصيب.http://matplotlib.sourceforge.net
فكر بايثون 127 الفصل الرابع عرش امللفات الثبات 14.1 persistance معظم الربامج اليت رأيناها حىت الان مؤقتة مبعىن أهنا تعمل لوقت قصري و تنتج بعض البياانت مث عند توقفها ختتفي بياانهتا و ان شغلت الربانمج من جديد فسيبدأ بداية نظيفة. الربامج الاخرى اثبتة: تعمل لوقت طويل )أو طوال ال وقت( حتتفظ ببعض بياانهتا عىل الاقل يف خم زانت دامئة )اكلقرص الصلب( و ان أوقفت و أعيد تشغيلها ستتابع من حيث توقفت. أنظمة التشغيل مثال عىل الربامج الثابتة )املثابرة( فهيي تبدأ مع تشغيل احلاسوب أو خادم الويب server( )web اليت تعمل طوال الوقت منتظرة دامئا الاوامر من الش بكة. من ابسط طرق احتفاظ الربامج ببياانهتا يه قراءة و كتابة ملفات النصوص لقد اس تخدمنا من قبل برامج تقرأ و تكتب ملفات النصوص. سرنى يف هذا الفصل برامج تكتب هذه الربامج. اطل رق البديةل يه ختزين حاةل الربانمج يف قاعدة بياانت. يف هذا الفصل سأقدم قاعدة بياانت بس يطة و مديول اذلي يسهل ختزين بياانت الربانمج. pickle 14.2 القراءة و الكتابة امللف النيص هو تسلسل من احلروف اهلزنة بشلك دامئ عىل وس يط اكلقرص الصلب أو ذاكرة فالش أو قرص مدمج. مر بنا كيفية فتح و قراءة ملف يف القسم 9.1. لكتابة ملف عليك أول فتحه يف الوضع w اكلربمرت الثاين: طريقة >>> fout = open('output.txt', 'w') >>> print fout <open file 'output.txt', mode 'w' at 0xb7eb2410> ان اكن امللف موجودا من قبل ففتحه بوضع الكتابة سميحو البياانت القدمية و يبدأ بداية نظيفة ذلكل كن حذرا! و ان مل يكن امللف موجودا من قبل فس يوجد ملف جديد. write تضع البياانت يف امللف: >>> line1 = "This here's the wattle,\n" >>> fout.write(line1) و أكر ر بأن اكئن امللف حيتفظ بأخر موقع اكن فيه فان نوديت write مرة أخرى س تضيف البياانت اىل هناية امللف: >>> line2 = "the emblem of our land\n" >>> fout.write(line2)
فكر بايثون 128 >>> fout.close() و عندما تنهتيي من الكتابة عليك اغالق امللف: 14.3 قرينة مؤث ر write :str تغيري الصيغة جيب أن تكون حمارف ذلكل ان أردان قمي أخرى يف امللف علينا حتويلها اىل حمارف. أسهل طريق ذلكل يه >>> x = 52 >>> fout.write(str(x)) الطريقة البديةل يه مؤثر الصيغة % عند اس تخدامه عىل أعداد حصيحة فانه يكون مؤثر مودولوس )القسمة بدون ابق( لكن ان اكن العامل الول حمارف يصبح املؤثر % مؤثر تغيري الصيغة. العامل الاول هو حمارف الصيغة و اذلي حيتوي عىل واحد أو أكرث من تسلسالت العامل الثاين, و النتيجة تكون حمارف. مثال تسلسل الصيغة d% يعين أن العامل الثاين س يصاغ كعدد حصيح )d اختصار ل ) decimal : النتيجة '42' يه حمارف و جيب عدم اخللط بيهنا و بني العدد الصحيح 42. لتسلسل الصيغة أن يظهر يف أي ماكن يف انلارف فباماكنك تضمني قمية يف امجلةل: الصيغ اليت س تحدد كيف سيصاغ >>> camels = 42 >>> '%d' % camels '42' >>> camels = 42 >>> 'I have spotted %d camels' % camels 'I have spotted 42 camels و ان اكن هناك أكرث من تسلسل صيغة يف انلارف فعىل القرينة الثانية أن تكون توبل ابلرتتيب. املثال التايل يس تخدم 's%' لصياغة حمارف: '%d' ليصيغ عدد حصيح '%g' لصياغة رمق حقيقي )و ل تسألين ملاذا( و يس تخدم كذكل >>> 'In %d years I have spotted %g %s' % (3, 01, 'camels') 'In 3 years I have spotted 01 camels' جيب أن يتساوى عدد عنارص التوبل مع عدد تسلسالت الصيغ يف انلارف. و كذكل عىل أمناط العنارص أن تكون كام يف تسلسالت الصيغ: >>> '%d %d %d' % (1, 2) TypeError: not enough arguments for format string >>> '%d' % 'dollars' TypeError: illegal argument type for built-in operation يف املثال الاول مل يكن هناك عنارص مبا فيه الكفاية و يف الثاين اكنت العنارص من المنط اخلطأ. مؤثر الصياغة هل قدرات لكنه صعب الاس تخدام ابماكنك القراءة أكرث عنه هنا.http://docs.python.org/2/library/stdtypeshtml#string-ormatting
14.4 أسامء امللفات و املسارات فكر بايثون 129 تنظم امللفات يف جمدلات )أو دليل( و للك برانمج شغال "جمدل حايل" و هو املدل الافرتاي ملعظم العمليات مثال عندما تفتح ملف للقراءة فسيبحث عنه ابيثون يف املدل احلايل. يوفر مديول احلايل: os اقرتاانت للعمل مع امللفات و املدلات os( من )operating system و os.get يه اختصار ل املدل الشغال احلايل directory(.)current working و اليت يه املدل القاعدة ملس تخدم امسه.dinsdale ترجع امس املدل >>> import os >>> cwd = osget.cwd() >>> print cwd /home/dinsdale cwd home/dinsdale/ النتيجة يف هذا الربانمج يه و حمارف ك cwd و اليت تتعرف عىل امللف تسمى مسار. و املسار النسيب يبدأ من املدل احلايل املسار املطلق يبدأ من من أعىل جمدل يف نظام امللفات. اكنت املسارات اليت رأيناها حىت الان اسامء ملفات بس يطة ذلكل فهيي ت نسب للمجدل احلايل. ليك جتد املسار املطلق مللف ميكنك اس تخدام : os.path.abspath تفحص >>> os.path.abspath('memo.txt') '/home/dinsdale/memotxt' open.path.exists اذا ما اكن امللف موجودا: و ان اكن موجودا س تفحص os.path.isdir اذا ما اكن جمدل: >>> os.path.exists('memo.txt') True >>> os.path.isdir('memo.txt') False >>> os.path.isdir('music') True أما os.path.isfile ترجع os.listdir فس تفحص اذاما اكن ملفا. قامئة ابمللفات )و املدلات الاخرى( من املدل املعطى: >>> os.listdir(cwd) ['music', 'photos', 'memo.txt'] و لس تعراض هذه الاقرتاانت "يطوف" املثال التايل يف جمدل و يطبع أسامء امللفات لكها و ينادي نفسه اجرتاراي عىل لك املدلات def walk(dirname): for name in os.listdir(dirname): path = os.path.join(dirname, name) if ospathisfile(path): print path else: walk(path)
يأخذ os.path.join فكر بايثون 130 امس املدل و امس امللف و يضمهام ليصبحا مسارا اكمال. مترين 14.1 يوفر املديول os اقرتاان امسه walk و هو شبيه ابلطواف يف املثال السابق لكنه متنوع أكرث. اقرأ واثئقه مث اس تخدمه لطباعة أسامء امللفات يف جمدل و اسامء املدلات الفرعية. احلل:.http://thinkpython.com/code/walk.py 14.5 التقاط الاس تثناءات كثرية يه الامور اليت قد ختفق عندما حتاول قراءة أو كتابة امللفات. فان حاولت فتح ملف غري موجود س تحصل عىل خطأ :IOError و ان كنت ل متكل احلق يف الوصول اىل ملف: >>> fin = open('bad_file') IOError: [Errno 2] No such file or directory: 'bad_file' >>> fout = open('/etc/passwd', 'w') IOError: [Errno 13] Permission denied: '/etc/passwd' و ان حاولت فتح جمدل للقراءة س تحصل عىل: >>> fin = open('/home') IOError: [Errno 21] Is a directory os.path.isfile os.path.exists و لتجنب لك هذه الخطاء ميكنك اس تخدام اقرتاانت مثل أن حفص لك الاحامتلت سيس تغرق الكثري من الوقت و من السطور الربجمية )ان نهبك اخلطأ فليكن أن هناك 21 شيئا قد خيفق(. Errno 21 الا. اىل يشء من الافضل أن متيض قدما و حتاول مث تتعامل مع املشالك عند حدوهثا و هو ابلضبط ما تقوم به عبارة.try حنو : if شبيه بنحو عبارة try يبدأ ابيثون بتنفيذ فقرة try و ان اكن لك يشء عىل ما يرام سيتخطى فقرة س يقفز خارج فقرة try و ينفذ فقرة.except try: fin = open('bad_file') for line in fin: print line fin.close() except: print 'Something went wrong' except أما ان حصل اس تثناء و تداول الخطاءابس تخدام try يسمى التقاط catching الاس تثناء.exception يف هذا املثال تطبع فقرة except رساةل خطأ لكهنا ليست ذات دلةل كبرية. يف العموم فان التقاط الاس تثناءات يسمح كل ابصالح املشلكة أو أن حتاول اثنية أو عىل الاقل أن توقف الربانمج بلباقة. مترين 14.2 اكتب اقرتاان امسه sed يأخذ كقرائن: حمارف منوذجية و حمارف بديةل و امسني مللفني. جيب أن يقرأ امللف الاول و يكتب حمتوايته يف امللف الثاين )ينشئ ملفا اثنيا ان تطلب الامر(. ان و جدت انلارف المنوذجية يف أي ماكن يف امللف فيجب أن تستبدل ابنلارف البديةل. ان ظهر خطأ خالل فتح أو قراءة أو اغالق امللفات جيب عىل برانجمك التقاط الاس تثناء مث يطبع رساةل وجود خطأ و خيرج من الربانمج احلل:.http://thinkpython.com/code/sed.py
قواعد البياانت 14.6 فكر بايثون 131 قاعدة البياانت يه ملف جمهز ليك خيزن البياانت. معظم قواعد البياانت منظمة كقاموس من انحية أهنا ختط من املفاتيح اىل القمي. الفرق الاكرب بيهنا أن قاعدة البياانت موجودة عىل قرص )أو أي وس يةل ختزين دامئة( فهيي بذكل اثبتة. يوفر املديول مللفات صور. anybm فتح قاعدة بياانت كفتح أي ملف اخر: واهجة لنشاء و تعديل ملفات قواعدالبياانت. و مكثال سأنشئ قاعدة بياانت حتتوي عىل اقتباسات >>> import anydbm >>> db = anydbm.open('captions.db', 'c') النسق c يعين أنه جيب انشاء قاعدة البياانت ان مل تكن منشأة أصال. و النتيجة يه قاعدة بياانت ميكن اس تخداهما )ملعظم العمليات( كام يس تخدم القاموس. فان أوجدت عنرصا جديدا فس ي ح دث anybm قاعدة البياانت: و ان مقت بتعيني أخر لي من املفاتيح فسيبدل >>> db['cleesepng'] = 'Photo of John Cleese' anybm القمية القدمية: >>> db['cleese.png'] = 'Photo of John Cleese doing a silly walk' >>> print db['cleesepng'] Photo of John Cleese doing a silly walk الكثري من طرق القواميس تعمل مع اكئنات قواعد البياانت. و يعمل معها أيضا التكرار بواسطة عبارة nfor و كام هو احلال مع امللفات الاخرى عليك اغالق قاعدة البياانت بعدما تنهتيي من معكل: for key in db: print key >>> db.close() التخليل 14.7 هناكل تقييد ل اس تخدام أي منط اخر. يأخذ Pickling.anydbm و هو أن الك من املفاتيح و القمي جيب أن تكون حمارف. و س تحصل عىل خطأ ان حاولت هنا سيساعدان مديول التخليل pickle فهو يرتمج أي نوع من الاكئنات تقريبا اىل حمارف مناسبة للتخزين يف قاعدة بياانت مث يرتمج انلارف اىل اكئنات مرة أخرى كام اكنت. pickle.dumps اكئنا كربمرت و يرجع حمارف متثهل dumps( يه اختصار dump string أفرغ انلارف يف..( : الصيغة هنا ليست واحضة للقراءة ابلنسبة للبرش لن املقصود هو تسهيل تأويلها من قبل >>> import pickle >>> t = [1, 2, 3] >>> pickle.dumps(t) '(lp0\ni1\nai2\nai3\na'.pickle pickle.loads )أيضا )load string يعيد بناء الاكئن: و رمغ أن الاكئن اجلديد هل نفس قمية القدمي ال أنه )يف العموم( ليس القدمي: >>> t1 = [1, 2, 3] >>> s = pickle.dumps(t1) >>> t2 = pickle.loads(s) >>> print t2 [1, 2, 3]
فكر بايثون 132 بلكامت اخرى فالتخليل و ازاةل التخليل )الطوزجة ( لها نفس تأثري نسخ الاكئنات. >>> t1 == t2 True >>> t1 is t2 False ميكنك اس تخدام pickle لتخزين غري انلارف يف قاعدة البياانت و هو أمر شائع دلرجة أنه كبسل يف مديول يسمى.shelve مترين 14.3 ان كنت قد محلت حيل للمترين 12.4 من.http://thinkpython.com/code/anagram_sets.py سرتى ابنه ينشئ قاموسا يصل ما بني حمارف )من احلروف( و قامئة اللكامت اليت ميكن هتجئهتا حبروف انلارف تكل مفثال.]'opts', 'post', 'pots', spot', 'tops' [ موصوةل ابلقامئة opst اكتب مديول يس تورد التصحيفي يف " فر " anagram_sets و read_anagrams http://thinkpython.com/code/anagram_db.py و يزودان ابقرتانني store_anagrams اذلي خيزن قاموس اجلناس اذلي يبحث عن لكمة و يرجع قامئة بلك جناساهتا. احلل: الانبيب 14.8 Pipes توفر معظم أنظمة التشغيل واهجة لسطر الاوامر تعرف أيضا ابلصدفة.Shell الصدفات يف العادة توفر أوامر للتنقل يف نظام امللفات و اطالق التطبيقات. مثال يف يونكس ميكن تغيري املدل ابس تخدام cd و عرض حمتوايته ب ls و اطالق مس تعرض ويب بطباعة )مثال(.firefox فأي برانمج ميكنك اطالقه من الصدفة ميكنك اطالقه من ابيثون أيضا ابس تخدام أنبوب.pipe الانبوب هو اكئن ميثل برانجما شغال. مثال يف يونكس يعرض المر )1( : ls -1 حمتوايت املدل احلايل )يف صيغة (. long ميكنك اطالق ب ls os.popen >>> cmd = 'ls -l' >>> fp = os.popen(cmd) تكون القرينة حمارف حتتوي أمر الصدفة و تكون قمية املرجتع اكئن يترصف كام يترصف امللف املفتوح. ميكنك قراءة اهلرجات من معلية ls سطرا بعد سطر ب readline أو قراءة لك يشء ب : read و عندما تنهتيي منه تغلقه كام تغلق ملف: املرجتع هو اخر حاةل لعملية >>> res = fp.read() >>> stat = fp.close() >>> print stat None و None تعين أن العملية انهتت بشلك عادي )بدون أخطاء( ls مثال معظم أنظمة يونكس هبا أمر امسه ميكنك القراءة عن MD5 md5sum يقرأ حمتوايت ملف و حيسب "checksum" أي "مجموع اختباري" من.http://en.wikipedia.org/wiki/Md5 يوفر هذا الامر طريقة فعاةل لختبار اذا ما اكن مللفان خمتلفان نفس انلتوى. فاحامتل تساوي املاميع الاختبارية نلتويني خمتلفني ضئيةل دلرجة الاهامل )قد حتدث ان اهنار الكون(.
ميكنك اس تخدام أنبواب لتشغيل md5sum فكر بايثون 133 من خالل ابيثون و حتصل عىل النتيجة: >>> filename = 'book.tex' >>> cmd = 'md5sum ' + filename >>> fp = os.popen(cmd) >>> res = fp.read() >>> stat = fp.close() >>> print res 1e0033f0ed0656636de0d75144ba32e0 booktex >>> print stat None مترين 14.4 ان اكنت دليك مجموعة خضمة من ملفات mp3 فقد تكون احداها أو أكرث نسخ لنفس الاغنية و لكهنا خمزنة ابمس اخر أو يف جمدل اخر. هدف هذا المترين هو البحث عن املكررات. 1. اكتب برانجما يبحث يف جمدل و يف جمدلاته الفرعية و يرجع قامئة بلك امللفات اليت ادخلت لحقهتا )مثل ).mp3 تلميح: العديد من الاقرتاانت املفيدة يف التالعب ابمللفات و أسامهئا موجودة يف. os.path 2. تس تطيع اس تخدام md5sum للتعرف عىل املتكررات عن طريق احتساب ال ( )checksum للك ملف فان اكن مللفني نفس احلسبة فعىل الاغلب هام تكرار لنفس انلتوى. 3. للتأكد من نتيجة الفحص ميكنك اس تخدام أمر يونكس.diff 14.9 كتابة املديولت لك ملف حيتوي عىل نص برجمي لبايثون ميكن اس ترياده مكديول. التايل: مثال ان اكن دليك ملف امسه wc.py به النص الربجمي def linecount(filename): count = 0 for line in open(filename): count += 1 return count ان شغلت هذا الربانمج فس يقرأ نفسه و يطبع عدد السطور يف امللف و اليت يه 7: أصبح دليك الان اكئن مديول امسه print linecount('wc.py') >>> import wc 7 >>> wc.linecount('wc.py') 7 : linecount اذن فهكذا تكتب مديول يف ابيثون. املشلكة الوحيدة يف هذا املثال يه أنك عندما تس تورد هذا املديول فانه ينفذ النص الربجمي عندما تس تورد مديول فانه يعر ف اقرتاانت جديدة لكنه ل ينفذها. الختباري يف السفل. عادة أصبحت popen غير مرغوبة أي يجب التوقف عن استخدامها و البدء باستخدام.subprocess لكن للحاالت البسيطة أجد أن subprocess معقدة أكثر من الالزم. لذلك سأستخدم popen حتى يزيلوها.
الربامج اليت ست س تورد مكديول لها يف الغالب الصيغة التالية: فكر بايثون 134 if name == ' main ': print linecount('wc.py') name main الاختبار. مترين متغري جاهز ي طلق عند ابتداء الربانمج. فان اكن الربانمج شغال كنص برجمي فان قمية name يه و يف هذه احلاةل سينفذ نص الاختبار. و ان مل يكن أي ان اكن مديول يمت اس ترياده فسيتخطى نص 14.5 اطبع هذا املثال يف ملف امسه wc.py مث شغهل كنص برجمي. مث شغل مف رس ابيثون و اس تورده اس تريادا import wc ما يه قمية main عندما اكن املديول مس توردا حتذير: ان اس توردت مديول كنت قد اس توردته من قبل فلن يفعل ابيثون أي يشء فال يعيد قراءة امللف حىت و ان ع دل عليه. ان أردت اعادة حتميل امللف عليك اس تخدام الاقرتان اجلاهز reload الا أنه خمادع بعض اليشء ذلا فأامن يشء هو اعادة بدء املف رس مث اس ترياد املديول من جديد. الخطاء عالج 14.10 عند قراءة و كتابة امللفات قد تقع يف مشالك مع املساحات البيضاء. هذه و السطور اجلديدة يف الغالب غري مرئية: هنا قد يساعدك الاقرتان اجلاهز البيضاء بتسلسالت من اخلطوط املائةل اليت قد تساعد يف عالج الاخطاء. الخطاء صعبة الاكتشاف لن مسافات اجلدوةل >>> s = '1 2\t 3\n 4' >>> print s 1 2 3 4 repr فهو يأخذ أي اكئن كقرينة و يرجع حمارف متثهل. و للمحارف تمتثل املساحات >>> print repr(s) '1 2\t 3\n 4' مشلكة اخرى قد تقع فهيا يه أن أنظمة التشغيل اهلتلفة تس تخدم حروفا خمتلفة للتعبري عن سطر جديد. مفهنا ما يس تخدم "سطر جديد "newline و تكتب n\ و مهنا ما يس تخدم return" رجوع" و تكتب r\ و مهنا ما يس تخدم لكهيام. فان نقلت امللفات بني هذه الانظمة الغري متوافقة فقد تتسبب ابملشالك. توجد تطبيقات يف معظم الانظمة حتول من صيغة اىل اخرى ابماكنك العثور علهيا )و القراءة عهنا( عىل.http://en.wikipedia.org/wiki/Newline طبعا ميكنك كتابة التطبيق اخلاص بك.
املعاين 14.11 فكر بايثون 135 اثبت :persistant تتعلق ابلربانمج اذلي يسمتر يف العمل اىل ما ل هناية و حيتفظ عىل الاقل جبزء من بياانته. مؤثر الصيغ :format operator مؤثر % يأخذ حمارف الصيغة و توبل و يودل حمارف حتتوي عىل عنارص التوبل مصاغة حسب ما حتدده حمارف الصيغة. حمارف الصيغة :format string حمارف تس تخدم مع مؤثر الصيغة و حتتوي عىل تسلسل الصيغة. تسلسل الصيغة :format sequence تسلسل من احلروف يف حمارف الصيغة مثل d% حيدد كيفية صياغة قمية ما. ملف نيص :text file تسلسل من احلروف خمزن بشلك دامئ عىل قرص صلب. جمدل :directory مجموعة من امللفات حتت امس واحد. مسار )مساق( :path حمارف حتدد امللف. مسار نس يب :relative path مسار يبدأ من املدل احلايل. مسار مطلق :absolute path مسار يبدأ يف أعىل موقع يف نظام امللفات. التقاط :catch منع الاس تثناء من اهناء الربانمج ابس تخدام عباريت try. و except قاعدة بياانت :database ملف تنظم حمتوايته عىل شلك جمدل ترتبط فيه املفاتيح ابلقمي املقابةل. متارين 14.12 مترين 146 هناك طرق يف مديول urllib للتعامل مع ال URL و حتميل املعلومات من الويب. املثال التايل حيمل و يطبع رساةل نصية من :thinkpython.com import urllib conn = urllib.urlopen('http://thinkpython.com/secret.html') for line in conn: print line.strip() شغل هذا النص و اتبع التعلاميت اليت س يظهرها. احلل:.http://thinkpython.com/code/zip_code.py
فكر بايثون 136
فكر بايثون 137 الفصل اخلامس عرش و الاكئنات الفئات تتوفرة أمثةل عىل نصوص الربجمة لهذا الفصل عىل.http://thinkpython.com/code/Point1.py و حلول الامترين موجودة عىل.http://thinkpython.com/code/Point1_soln.py 15.1 أمناط عر فها املستخدم User-defined types لقد اس تخدمنا الكثري من امناط ابيثون اجلاهزة لقد حان الوقت لتعريف أمناط جديدة. و عىل سبيل املثال س ننشئ منطا امسه Point سميثل نقطة يف فراغ ثنايئ الابعاد. يف عرف الرايضيات تكتب النقاط بني قوسني و تفصل بني احداثياهتا فاصةل. مثال )0,0( متثل نقطة الاصل و )س,ص( متثل النقطة اليت تبعد س وحدات اىل الميني و ص وحدات اىل العىل من نقطة الاصل. هناكل العديد الطرق اليت ميكننا متثيل النقاط هبا يف ابيثون: ميكننا ختزين الحداثيات بشلك منفصل يف متغريين س و ص. ميكننا ختزيهنا كعنارص يف قامئة أو توبل. ميكننا انشاء منط جديد ميثل النقاط كاكئنات. انشاء منط جديد معقد قليال اذا ما قورن ابخليارين الاخريني الا أن هل حس نات س تتبدى كل برسعة. المنط اذلي يعر فه املس تخدم يسمى فئة.Class و تعريف الفئة يكون اكلتايل: class Point(object): """Represents a point in 2-D space""" تشري الرتويسة اىل أن الفئة اجلديد يه نقطة و اليت يه عبارة عن object ما و اذلي هو منط جاهز. ا نتمل عبارة عن حمارف للتوثيق ترشح الهدف من الفئة. ميكنك تعريف اقرتاانت و متغريات داخل الفئة س نعود لهذا فامي بعد. و بتعريف فئة امسها Point س ي خلق اكئن فئة 3.0 Point blank x y 4.0 الشلك 15.1: رمس للاكئن
فكر بايثون 138 و لن تعريف Point اكن يف املس توى الاعىل فان امسها الاكمل اكئن الفئة اكملصنع اذلي ينتج الاكئنات. و لتنتج نقطة ستنادي Point كهنا اقرتان: >>> print Point <class ' main Point'> يكون. main.point: >>> blank = Point() >>> print blank < main Point instance at 0xb7e9d3ac>.blank و القمية املرجعة يه مرجع لاكئن Point اذلي نعينه ل يسمى اجياد اكئن جديد ابلتجلية instantiation و الاكئن املنشأ يسمى instance of the class جتلية للفئة. و عندما تطبع جتلية فس يخربك ابيثون اىل أي فئة تنمتي و يف أي ماكن خزنت يف اذلاكرة )البادئة 0x تعين أن ما يلهيا هو رمق سدايس عرشي(. اخلصال 15.2 Attributes: مبكنك تعيني قمي للتجلية ابس تخدام التنويت ابلنقاط :dot notation يشبه هذا النحو النحو اذلي يس تخدم لختيار العنارص من مديول مثل mathpi مع أننا يف هذه احلاةل نعني قامي لعنارص مسامة يف الاكئن. هذه العنارص تسمى خصال.attributes >>> blank.x = 3.0 >>> blank.y = 4.0 أو string.whitespace اللكمة attribute يه امس و التاء فهيا مشددة خالفا للفعل. atribute يبني الرمس التايل نتيجة هذه التعيينات. رمس احلاةل اذلي يعرض الاكئن و خصاهل يسمى رمس الاكئن object diagram أنظر الشلك 15.1. مرجع الاكئن Point هو املتغري حقيقي. blank ميكنك قراءة قمية اخلصةل ابس تخدام نفس النحو: و حيتوي هذا الاكئن عىل و هو حيتوي عىل خصلتني لك مهنام تشري اىل عدد >>> print blank.y 4.0 >>> x = blank.x >>> print x 3.0 التعبري blank.x يعين "اذهب اىل الاكئن اذلي مرجعه blank حنن يف هذه احلاةل نعني تكل القمية للمتغري x و ل يوجد تعارض بني املتغري ميكنك اس تخدام النتوتة كجزء من أي تعبري, مثال: ميكنك مترير جتل ية كقرينة ابلطريقة املعتادة مثال: و أحرض قمية x". x و اخلصةل x. >>> print '(%g, %g)' % (blank.x, blank.y) (3.0, 4.0) >>> distance = math.sqrt(blank.x**2 + blank.y**2) >>> print distance 5.0
فكر بايثون 139 def print_point(p): print '(%g, %g)' % (p.x, p.y) هنا print_point تأخذ نقطة كقرينة و تعرضها بنتوتة رايضية< و لس تدعاهئا ميكنك مترير blank كقرينة: يف داخل الاقرتان p يه امس مرجع متعدد من plank فان عدل الاقرتان عىل p >>> print_point(blank) (3.0, 4.0) ستتغري.blank مترين 15.1 اكتب اقرتاان امسه distance_between_points يأخذ نقطتني كقرائن و يرجع املسافة بيهنام. 15.3 املس تطيالت أحياان يكون من الواحض ماذا جيب أن تكون خصال اكئن ما لكن يف أحيان أخرى عليك اختاذ القرارات. فتخيل مثال أنك تصمم فئة لمتثيل املس تطيالت. مفا يه اخلصال اليت ستس تعملها لتحديد موقع و جحم املس تطيل للتسهيل ميكنك جتاهل الزوااي فاملس تطيل اما أفقي أو معودي. هناك احامتلن عىل الاقل: ميكنك حتديد ركن املس تطيل )أو حىت مركزه( و العرض و الطول. ميكنك حتديد ركنان متقابالن. حىت هذه اللحظة ل نس تطيع التفضيل بني الاحامتلني ذلكل س نطبق اخليار الاول مكثال فقط: هذا هو تعريف الاقرتان: يع دد نص التوثيق اخلصال: width class Rectangle(object): """Represents a rectangle attributes: width, height, corner """ و height و لمتثيل مس تطيل عليك أنشاء جتلية لاكئن املس تطيل مث تعني قمي للخصال: هام عددان و corner يه اكئن نقطة حيدد الركن السفيل اليرس. الشلك 152 رمس الاكئن box = Rectangle() box.width = 100.0 box.height = 200.0 Box.corner = Point() Box.corner.x = 0.0 Box.cornery = 00 width height corner 100.0 200.0 Point x 0.0 y 0.0 التعبري box.corner.x يعين "اذهب اىل الاكئن اذلي مرجعه box و اخرت من هناك اخلصةل اليت امسها corner مث اذهب اىل ذكل الاكئن و اخرت اخلصةل اليت امسها x."
فكر بايثون 140 embedded يبني الشلك 15.2 مضم ن. حاةل هذا الاكئن و يه حاةل اكئن عندما يكون خصةل لاكئن اخر. تسمى هذه احلاةل كقمي مرجتعة التجليات 15.4 ميكن لالقرتاانت أن ترجع جتليات. احداثيات مركز املس تطيل: يف املثال التايل ميرر box كقرينة و تعني النتيجة مفثال find_center تأخذ Rectangle كقرينة و ترجع Point حتتوي عىل def find_center(rect): p = Point() p.x = rect.corner.x + rect.width/2.0 p.y = rect.corner.y + rect.height/2.0 return p : center اىل Point >>> center = find_center(box) >>> print_point(center) (50.0, 100.0) ليست ثبيتة الاكئنات 15.5 ميكنك تغيري حاةل الاكئن بعمل تعيني لحدى خصاهل. مفثال لتغيري جحم املس تطيل بدون تغيري موقعه ميكنك تعديل قمي : height و width و ميكنك أيضا كتابة اقرتاانت تعدل عىل الاكئنات. مثال dwidth و dheight و تضيف هذه الارقام لعرض و طول املس تطيل: املثال التايل يعرض التأثري: يف داخل الاقرتان اكن Box.width = box.width + 50 Box.height = box.width + 100 grow_rectangle تأخذ اكئن املس تطيل و رمقني def grow_rectangle(rect, dwidth, dheight): rect.width += dwidth rect.height += dheight >>> print box.width 100.0 >>> print box.height 2000 >>> grow_rectangle(box, 50, 100) >>> print box.width 150.0 >>> print box.height 300.0 rect rect واحدا من مراجع متعددة ل box مترين 15.2 اكتب اقرتاان امسه move_rectangle يأخذ رمقني dx اىل الاحدايث x ل corner و dy اىل الحدايث y ل.corner فان عدل الاقرتان عىل سيتغري box أيضا و dy جيب أن يغري موقع املس تطيل ابضافة dx
النسخ 15.6 فكر بايثون 141 تعدد املرجعيات قد جيعل قراءة الربامج صعبة لن التغيري يف ماكن ما س يكون هل تأثري غري متوقع يف ماكن اخر. من الصعب مالحقة لك املتغريات اليت قد تتعلق بذكل الاكئن. نسخ الاكئنات عادة ما يكون البديل لتعدد املرجعيات. حيتوي املديول أي اكئن: عىل الاقرتان copy copy اذلي ميكنه مضاعفة >>> p1 = Point() >>> p1.x = 3.0 >>> p1.y = 4.0 >>> import copy >>> p2 = copy.copy(p1) حيتوي p1 و p2 عىل نفس البياانت لكهنام ليسا نفس النقطة: >>> print_point(p1) (3.0, 4.0) >>> print_point(p2) (3.0, 4.0) >>> p1 is p2 False >>> p1 == p2 False املؤثر is يشري اىل أن p1 و p2 ليسا نفس الاكئن و هو ما توقعناه. قد تكون توقعت أيضا أن == س تنتج True لن هذه الاكئنات حتتوي عىل نفس البياانت. يف هذا احلال فقد خاب ظنك لنك س تعرف الن أنه يف بعض احلالت يكون ترصف == كترصف is فهذا املؤثر س يفحص هوية الاكئن و ليس تساوي الاكئن. هذا السلوك ميكن تغيريه سرنى فامي بعد كيف. ان اس تخدمت copy.copy لنسخ مس تطيل سرتى بأهنا تنسخ الاكئن و ليس النقطة اليت يتضمهنا. الشلك 153 رمس الاكئن box1 width height corner 100.0 200.0 >>> box2 = copy.copy(box) >>> box2 is box False >>> box2.corner is box.corner True Point x 0.0 y 0.0 100.0 200.0 width height corner box2 يظهر الشلك 15.3 ما يبدو عليه رمس الاكئن. تسمى العملية نسخ حضل لهنا تنسخ الاكئن و أي مراجع قد حيتوهيا لكن ل تنسخ الاكئنات املضمنة فيه. يف معظم التطبيقات لن يكون هذا ما تريده. يف هذا املثال اس تدعاء grow_rectangle عىل أحد املس تطيلني لن يؤثر عىل الاخر لكن اس تدعاء move_rectangle س يؤثر عىل الاخر! و هذا السلوك مشوش و مرتع للخطأ. لكن حلسن احلظ فان دلى املديول copy طريقة امسها deepcopy و يه ل تنسخ الاكئن فقط بل الاكئنات اليت يشري الهيا أيضا و الاكئنات اليت تشري الهيا و هكذا لعكل لن تفاجأ من تسمية هذه العملية ابلنسخ العميق.
فكر بايثون 142 >>> box3 = copy.deepcopy(box) >>> box3 is box False >>> box3.corner is box.corner False الاكئنان box3 و box مترين خمتلفان متاما. 15.3 اكتب نسخة من move_rectangle ختلق و ترجع مس تطيال جديدا بدل من التعديل عىل القدمي. الخطاء عالج 15.7 عند ابتدائك العمل عىل الاكئنات ستصادفك اس تثناءات جديدة ان حاولت مثال الوصول اىل خصةل غري موجودة س تحصل عىل :AttributeError >>> p = Point() >>> print p.z AttributeError: Point instance has no attribute 'z' ان مل تكن متأكدا من منط الاكئن فميكنك السؤال: >>> type(p) <type ' main Point'> و ان مل تكن متأكدا ان اكن للاكئن خصةل معينة فميكنك اس تخدام الاقرتان اجلاهز : hasattr للقرينة الاوىل أن تكون أي اكئن و تكون القرينة الثانية حمارف حتتوي عىل امس اخلصةل. >>> hasattr(p, 'x') True >>> hasattr(p, 'z') False املعاين 15.8 فئة : Class منط يعرفه املس تخدم. تعريف الفئة ينشئ اكئن فئة جديد. اكئن فئة :class object اكئن حيتوي عىل معلومات عن منط عرفه املس تخدم. جتل ية : instance اكئن ينمتي اىل فئة. خصةل : attribute أحد القمي املسامة املرتبطة باكئن. )اكئن( متضمن ( (object :embedded اكئن خمزن كخصةل داخل اكئن اخر. نسخ حضل : shallow copy أن تنسخ حمتوايت اكئن مبا فهيا أي مراجع لاكئنات مضمنة و يس تخدم فهيا الاقرتان copy من املديول.copy نسخ معيق : deep copy أن تنسخ حمتوايت اكئن و تنسخ أيضا الاكئنات املضمنة فيه و الاكئنات املضمنة فهياو هكذا يس تخدم فهيا الاقرتان deepcopy من املديول. copy رمس الاكئن : object diagram رمس يظهر الاكئنات و خصالها و قمي خصالها.
15.9 مترين متارين 15.4 يوفر سوميب Swampy )انظر الفصل 4( مديول امسه و ميكنك اس ترياده اكلتايل: فكر بايثون 143 World World أو حس امب نصبت سوميب قد يكون هكذا: النص التايل ينشئ اكئن World مث ينادي عىل طريقة و اذلي يعر ف منطا عر فه املس تخدم امسه from swampy.world import World from World import World mainloop اليت تنتظر املس تخدم. world = World() world.mainloop() س تظهر انفذة علهيا رشيط العنوان و مربع فارغ. سنس تخدم هذا املربع لرمس النقاط و املس تطيالت و الاشاكل الاخرى أضف السطور التالية قبل نداء mainloop مث شغل الربانمج مرة أخرى. canvas = world.ca(width=500, height=500, background='white') bbox = [[-150,-100], [150, 100]] canvas.rectangle(bbox, outline='black', width=2, fill='green4') جيب أن ترى الان مس تطيال أخرضا حبدود سوداء< السطر الاول س يوجد مقاشة الرمس و اليت س تظهر مكربع أبيض. لاكئن القامشة طرق مثل rectangle لرمس الاشاكل اهلتلفة. bbox يه قامئة قوامئ متثل "صندوق التحديد"للمس تطيل. أول زوجني من الاحداثيات هام زاوية املس تطيل السفىل اىل اليسار و الزوجني الثانيني للزاوية العليا الميىن. ابماكنك رمس دائرة هكذا: الربمرت الاول هو زويج احداثيات مركز ادلائرة و الثاين هو نصف القطر. Canvas.circle([-25,0], 70, outline=none, fill='red') ان أضفت هذا السطر للربانمج فيجب أن حتصل عىل العمل الوطين لبنغالدش )أنظر.)http://en.wikipedia.org/wiki/Gallery_of_sovereign-state_flags.1.2.3.4.5 اكتب اقرتاان امسه draw_rectangle يأخذ مقاشة و مس تطيال كربمرتات و يرمس متثيال للمس تطيل عىل القامشة. أضف خصةل امسها color لاكئنات املس تطيل مث عدل عىل draw_rectangle حبيث يس تخدم خصةل color لتغيري لون املس تطيل. اكتب اقرتاان امسه draw_point يأخذ مقاشة و نقطة كقرائن مث يرمس متثيال للنقطة عىل القامشة. عرف فئة جديدا امسها Circle لها اخلصال املناسبة. مث أنشئ جتليات لاكئن. Circle اكتب اقرتاان امسه draw_circle يرمس دوائر عىل القامشة. اكتب برانجما يرمس عمل مجهورية التشيك تلميح: ميكنك رمس املضلع هكذا: points = [[-150,-100], [150, 100], [150, -100]] canvas.polygon(points, fill='blue') لقد كتبت برانجما صغريا يرسد الالوان املتاحة تس تطيع حتميهل من: http://thinkpython.com/code/color_lis.tpy
فكر بايثون 144 الفصل السادس عرش الفئات و الاقرتاانت أمثةل النصوص الربجمية لهذا القسم متوفرة من: http://thinkpython.com/code/time1.py الوقت 16.1 س نعر ف فئة امسها الاقرتان يكون اكلتايل: مث ميكننا انشاء اكئن أخر مكثال Time عىل الامناط اليت يعرفها املس تخدم. و يه تسجل الوقت ابلنس بة لليوم. تعريف class Time(object): """Represents the time of day. attributes: hour, minute, second """ Time جديد و تعيني خصال للساعات و ادلقائق و الثواين: time = Time() time.hour = 11 time.minute = 59 time.second = 30 رمس احلاةل لاكئن Time يبدو كام يف الشلك 16.1. مترين 16.1 اكتب اقرتاان امسه print_time يأخذ اكئن Time و يطبعه عىل شلك ساعات:دقائق:ثوانيتلميح: يطبع التسلسل '%2d' اقسام الاعددا حصيحا من خانتني عىل الاقل و يس بقها 0 ان تطلب الامر. مترين 16.2 اكتب اقرتاان بوليانيا امسه يأيت بعد t2 زمنيا و الفسريجع. False is_safer يأخذ اكئين هام t1 و t2 Time و يرجع True ان اكن t1 16.2 الاقرتاانت البحتة س نكتب يف الاقسام القليةل القادمة اقرتانني مجلع قمي الوقت. و هام يعرضان نوعني من الاقرتاانت: الاقرتاانت البحتة و املعد لت. و هام يرشحان أيضا خطة تطوير أأمس هيا المنوذج املصغر و الرتقيع.Prototype and patch و يه طريقة للتعامل مع املشالك املعقدة بعمل منوذج مصغر و منم التعامل مع التعقيدات لكام تطورت. time time hour minute second 11 59 30 الشلك 16.1: رمس الاكئن
فكر بايثون 145 هنا منوذج مصغر من :add_time def add_time(t1, t2): sum = Time() sum.hour = t1.hour + t2.hour sum.minute = t1.minute + t2.minute sum.second = t1.second + t2.second return sum ينشئ الاقرتان اكئن Time جديد و هيييء خصاهل مث يرجع مرجعا لهذا لاكئن اجلديد. يسمى هذا اقرتان حبت لنه ل يعدل عىل أي من الاكئنات اليت مررت اليه كقرائن. و ليس هل تأثري كعرض قمية أو احلصول عىل مدخل من املس تخدم غري ارجاع قمية. من أجل حفص هذا الاقرتان سأنشئ اكئين Time اثنني: start و اذلي حيتوي عىل وقت البدء لفمل مثل "مونيت ابيثون و الكس املقدسة" و duration اذلي حيتوي عىل زمن تشغيل الفمل و اذلي هو ساعة و 35 دقيقة. مث س يعمل add_time مىت س ينهتيي عرض الفمل. >>> start = Time() >>> start.hour = 9 >>> start.minute = 45 >>> start.second = 0 >>> duration = Time() >>> duration.hour = 1 >>> duration.minute = 35 >>> duration.second = 0 >>> done = add_time(start, duration) >>> print_time(done) 10:80:00 قد ل تكون النتيجة 10:80:00 ما تأملته. اشلكة الاقرتان أنه ل يتعامل مع احلالت اليت تكون جماميع الثواين أو ادلقائق أكرب من س تني. عندما حيصل هذا فان علينا "محل" الثواين الزائدة اىل معود ادلقائق أو ادلقائق الزائدة اىل معود الساعات. هاك نسخة حمس نة: def add_time(t1, t2): sum = Time() sumhour = t1.hour + t2.hour sum.minute = t1.minute + t2.minute sum.second = t1.second + t2.second if sum.second >= 60: sum.second -= 60 sum.minute += 1 if sum.minute >= 60: sum.minute -= 60 sum.hour += 1 return sum رمغ أن هذا الاقرتان حصيح ال أنه ابتدأ ابلتضخم سرنى بدائل أقرص فامي بعد.
املعد لت 16.3 فكر بايثون 146 من املفيد لالقرتان أحياان أن يعدل عىل الاكئنات اليت مترر اليه كربمرتات. و يف هذه احلاةل تكون التغيريات مرئية ابلنسبة للمنادي. الاقرتاانت اليت تعمل هكذا تسمى معدلت. ف رسيعة: increment اذلي يضيف عدد معط ى ى من الثواين اىل اكئن Time ميكن كتابته طبيعيا مك عد ل. اليك مسودة def increment(time, seconds): time.second += seconds if time.second >= 60: time.second -= 60 time.minute += 1 if time.minute >= 60: time.minute -= 60 time.hour += 1 يقوم السطر الاول ابلعملية الاساس ية و البايق يتعامل مع احلالت اخلاصة اليت رأيناها من قبل. أهذا اقرتان حصيح ما اذلي س يحدث ان اكن الربمرت seconds أكرب من س تني ل يكفي يف هذه احلاةل أن يكون المحل مرة واحدة فيجب أن نكرر المحل اىل أن تصبح قمية seconds أقل من س تني. أحد احللول هو استبدال عبارة for بعبارة while س يجعل هذا التعديل الاقرتان حصيحا لكن ليس كفؤا جدا مترين 16.3 اكتب نسخة حصيحة من increment ل حتتوي عىل أي حلقة. ميكن لالقرتان البحت أن يقوم بأي يشء يقوم به املعد ل. بل أن بعض لغات الربجمة ل تسمح ال ابلقرتاانت البحتة. و هناك بعض الادةل بأن الربامج اليت حتتوي عىل اقرتاانت حبتة ت ط ور أرسع و بأخطاء أقل من تكل اليت تس تخدم املعدلت. لكن املعدلت مناسبة للوقت و برامج الاقرتاانت أقرب اىل أن تكون أقل كفاية. يف العموم أنصحك ابس تخدام الاقرتاانت البحتة طاملا اكن اس تعاملها مربرا. و الالتجاء اىل املعدلت فقط ان اكنت احلسنات مغرية. هذه املقاربة تسمى أسلوب الربجمة الوظائفي. مترين 16.4 اكتب نسخة حبتة من increment تنشئ و ترجع اكئن Time جديد بدل من تعديل الربمرتات. الامنذج املصغرة 16.4 مقابل التخطيط امس خطة التطوير اليت أعرضها هو "الامنذج املصغرة و الرتقيع". للك اقرتان كتبت منوذج مصغر يقوم ابحلس بة الساس ية مث اختربته و كنت أرقع الخطاء لكام ظهرت يف طريقي. قد يكون هذا التقرب فعال ان مل يكن دليك الفهم العميق للمشلكة. لكن التصحيح التدرجيي عن طريق الزايدة قد يودل برانجما معقدا بال داعي )حيث أنه يتعامل مع العديد من احلالت اخلاصة(. و أيضا ل يعمتد عليه )خصوصا أنك لن تتأكد أنك عرثت عىل لك الاخطاء(. البديل هو التطوير اهلطط هل و فيه ت سه ل البصرية الربجمة كثريا. يف حالتنا هذه البصرية يه أن اكئن رمق من ثالثة خاانت قاعدته 60 أنظر Time هو يف احلقيقة!http://en.wikipedia.org/wiki/Sexagesimal
فكر بايثون 147 خصةل seconds يه خانة الاحاد و خصةل minutes يه خانة "الس تينات" و خصةل الساعات يه خانة "الست و ثالثني مئات!" عندما كتبنا معود اىل العمود الاعىل. و add_time increment كنا نقوم بعملية امجلع عىل القاعدة 60 و لجل ذكل كنا نقوم ابلمحل من أما ما لحظناه الن فهو يقرتح علينا مقاربة اخرى للمشلكة كلك: بوسعنا حتويل اكئنات اس تغالل كون احلاسوب يعرف كيف يق وم ابلعمليات احلسابية عىل الاعداد الصحيحة. اليك اقرتاان حيول الوقات )اكئنات )Time اىل أعداد حصيحة: و هنا اقرتان حيول الاعداد الصحيحة اىل أوقات )تذكر بأن البايق كتوبل(: اىل Time أعداد حصيحة و def time_to_int(time): minutes = time.hour * 60 + time.minute seconds = minutes * 60 + time.second return seconds divmod تقسم القرينة الاوىل عىل الثانية و ترجع الناجت و def int_to_time(seconds): time = Time() minutes, time.second = divmod(seconds, 60) time.hour, time.minute = divmod(minutes, 60) return time ليك تقنع نفسك بأن هذه الاقرتاانت حصيحة قد يتطلب الامر بعض التفكري و القيام ببعض الاختبارات. هناك طريقة لفحصها! اخترب اذا ما اكن: time_to_int(int_to_time(x))==x لعدة قمي. اكن هذا مثال عىل حفص التناسق. و مبجرد اقتناعك بأهنا حصيحة اس تخدهما لعادة كتابة : add_time مترين def add_time(t1, t2): seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) و هذه النسخة أصغر و أسهل للتأكد من الاوىل. 16.5 أعد كتابة increment ابس تخدام time_to_int و.int_to_time يكون التحويل أحياان من القاعدة 60 اىل القاعدة 10 أصعب من التعامل مع الوقت حتويل العد من قاعدة لخرى عسري عىل الفهم أفضل حدس نا يف التعامل مع قمي الوقت. لكن ان اكنت دلينا البصرية من البداية للتعامل مع الوقت كعداد قاعدهتا س تني. و استمثرانها يف كتابة اقرتاانت التحويل time_to_int( و.)int_to_time لكنا قد حصلنا عىل برانمج أقرص و أسهل للقراءة و عالج الخطاء و يعول عليه. أيضا من السهل اضافة مزااي جديدة هل مس تقبال مثال ختيل اجياد الفرق بني زمنني للحصول عىل قمية ما مىض من الوقت. السذج مه من س يطرحون ابلقرتاض لن اس تعامل اقرتان التحويل أسهل و عىل الاغلب أحص. املفارقة أن تصعيب املشلكة )أو تعمميها( قد يسهلها أحياان. )لن هناكل حالت خاصة اقل من و الاقل من فرص الاخطاء(.
الخطاء عالج 16.5 فكر بايثون 148 يكون اكئن Time مضبوطا ان اكنت قمي ادلقائق و الثواين بني 0 و 60 )متضمنة الصفر و لكن ليس الس تني( و ان اكنت قمية الساعات موجبة. قمي hour و minute جيب أن تكون أعداد حصيحة أما الثواين فيسمح لها ابلكسور. متطلبات كهذه تسمى "ل متغرية" لن علهيا أن تكون دامئا True أو مبعىن اخر ان مل تكن True فهناك خطأأ ما. كتابة نص يفحص الالمتغريات مفيد يف اقتناص الخطاء و العثور عىل مسبباهتا. مفثال ليكن دليك اقرتاان امسه valid_time يأخذ اكئن Time و يرجع False ان اكن خيالف أحد الثوابت: def valid_time(time): if time.hour < 0 or time.minute < 0 or time.second < 0: return False if time.minute >= 60 or time.second >= 60: return False return True مث يف بداية لك اقرتان ميكنك اختبار اذا ما اكنت القرائن ل ختالف الال املتغريات: أو ميكنك اس تخدام عبارة def add_time(t1, t2): if not valid_time(t1) or not valid_time(t2): raise ValueError('invalid Time object in add_time') seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) assert اليت تفحص الال املتغري و تقدم اس تثناءا ان فشل يف الفحص: def add_time(t1, t2): assert valid_time(t1) and valid_time(t2) seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) املفيد يف عبارات assert يه أهنا تفرق بني النص اذلي يتعامل مع احلالت العادية و النص املكتوب لفحص الاخطاء. املعاين 16.6 المنوذج املصغر و الرتقيع :prototype and patch أسلوب يف تطوير الربامج تكتب فيه مسودة رسيعة للربانمج مث تشغل و ختترب و لكام ظهر خطأ يعاجل. التطوير بناءا عىل خطة :planned programming اسلوب يف تطوير الربامج يعمتد عىل البصرية الثاقبة يف النظر اىل املشالك و عىل التخطيط أكرث منه التطوير العصايم أو المنوذج املصغر. اقرتان حبت :pure function اقرتان ل يعدل عىل الاكئنات اليت مترر هل كقرائن. معظم الاقرتاانت البحتة اقرتاانت ممثرة. املعدل :modifier اقرتان يعدل عىل اكئن أو أكرث مما مرر اليه كقرائن. معظم املعدلت اقرتاانت عقمية. ل املتغري :invariant رشط جيب أن يصح دامئا قبل تنفيذ الربانمج.
متارين 16.7 فكر بايثون 149 أمثةل نصوص الربجمة لهذا الفصل متوفرة عىل.http://thinkpython.com/code/Time1.py احللول لهذه الامترين متوفرة من.http://thinkpython.com/code/Time1_soln.py مترين 16.6 اكتب اقرتاان امسه رضب الوقت الاصيل و الرمق. mul_time يأخذ اكئن مث اس تخدم mul_time لكتابة اقرتان يأخذ اكئن Time جديد ميثل معدل الرسعة )الزمن للك وحدة مسافة(. Time و رمق. و يرجع اكئن Time Time جديد حيتوي عىل حاصل ميثل وقت الهناية لس باق و رمق ميثل املسافة و يرجع اكئن مترين 16.7 يوفر مديول datetime اكئنني date و time و هام شبهيان ب Date و Time اذلان يف هذا عىل واثئقها اقرأ املؤثرات و الطرق من غنية مجموعة توفر أهنا ال الفصل.http://docs.python.org/2/library/datetime.Html اكتب برانجما ابس تخدام مديول datetime حيصل عىل التارخي احلايل و يطبع امس اليوم. 1. اكتب برانجما يأخذ اترخي امليالد للمس تخدم مكدخل و يطبع عدد الاايم و الساعات و ادلقائق و الثواين املتبقية 2. حىت عيد ميالده القادم. يكون للشخصني اذلين ودلا يف أايم خمتلفة يوم يكون فيه سن أحدهام ضعف سن الثاين و هو "يوم الضعف" 3. اكتب برانجما يأخذ اترخيي ميالد مث حيسب هلام "يوم الضعف". 4. لزند التحدي قليال اكتب برانجما حيسب اليوم اذلي يكون فيه أحدمه أكرب ب n مرة من الاخر.
فكر بايثون 150 الفصل السابع عرش الفئات و الطرق أمثةل النصوص الربجمية لهذا الفصل موجودة عىل.http://thinkpython.com/code/Time2.py 17.1 مزااي الربجمة اكئنية املنحى ابيثون يه لغة اكئنية املنحى أي أهنا توفر مزااي تدمع هذا املنحى يف الربجمة. ليس من السهل تعريف الربجمة اكئنية املنحى الا أننا رأينا بعضا من صفاهتا: الربامج مبنية من تعريفات لاكئنات و لقرتاانت و يعرب عن معظم معليات احلوسبة فهيا بعمليات و اكئنات. لك تعريف لاكئن مرتبط مبفهوم ما أو اكئن ما يف الواقع. و الاقرتاانت تعمل عىل ذكل الاكئن بطريقة مقرونة بتكل اليت تتعامل فهيا الاكئنات مع بعضها يف الواقع. مثال فئة Time اليت عرفت يف الفصل 16 ترتبط ابلطريقة اليت يسجل فهيا الناس الوقت اليويم و الاقرتاانت اليت عرفناها هناك ترتبط ابلش ياء اليت يقوم هبا الناس بعد معرفهتم الوقت. و بنفس املنطق فئات Point و Rectangle ترتبط ابملفهوم الرايي للنقطة و املس تطيل. حىت هذه اللحظة مل نس تغل بعد املزااي اليت يوفرها ابيثون دلمع الربجمة اكئنية املنحى. هذه املزااي ليست رضورية حرفيا فكثري مهنا عبارة عن تراكيب حنوية بديةل للقيام بأش ياء مقنا هبا بدوهنا. لكن يف العديد من احلالت تكون البدائل أكرث اجيازا و تنق ل لنا بناء الربانمج بشلك أدق. مثال يف برانمج Time ل توجد عالقة واحضة بني تعريف الفئة و تعريف الاقرتان اذلي يتبعها. و ابلقليل من الاختبار س يتبني أن لك اقرتان يأخذ عىل الاقل اكئن Time واحد كقرينة. و هذه املالحظة يه ادلافع للعمل مع الطرائق الطريقة يه اقرتان مربوط بفئة معينة. لقد رأينا طرائق للمحارف و القوامئ و القواميس و التوبل يف هذا الفصل س نعر ف طرائق املستخدم. دلليا فالطرائق اكلقرتاانت أل أن هناك فرقان حنواين بيهنام: الطرائق معرفة داخل الفئات ليك جتعل العالقة بني الفئة و الطريقة مبارشة. حنو الاس تدعاء لطريقة خيتلف عن حنو نداء الاقرتان. يف الاقسام القليةل القادمة س نأخذ الاقرتاانت من الفصول السابقة و حنولها اىل طرائق. و هذا التحويل هو مياكنييك حبت و ميكنك القيام به عن طريق اتباع خطوات واحضة ان أصبح التحويل من شلك لخر ل يتعبك فس ميكنك اختيار أفضل الاشاكل اليت تناسب املهمة اليت تقوم هبا.
17.2 طباعة الاكئنات عرفنا يف الفصل 16 فئة امسها Time فكر بايثون 151 و يف المترين 16.1 كتبت اقرتاان امسه :print_time class Time(object): """Represents the time of day""" def print_time(time): print '%2d:%2d:%2d' % (time.hour, time.minute, time.second) و لنداء هذا الاقرتان اكن عليك مترير اكئن Time لك ما يلزمنا معهل لتحويل املسافات البادئة: كقرينة: >>> start = Time() >>> start.hour = 9 >>> start.minute = 45 >>> start.second = 00 >>> print_time(start) 09:45:00 print_time اىل طريقة هو نقل تعريف الاقرتان يف لحظ التغري داخل الفئة. اىل class Time(object): def print_time(time): print '%2d:%2d:%2d' % (timehour, timeminute, timesecond) أصبح هناك الان طريقتان لنداء.print_time الاوىل )القل ش يوعا( يه اس تخدام حنو الاقرتاانت: يف اس تخدام التنويت هنا اكن كربمرت. >>> Timeprint_time(start) 09:45:00 start Time هو امس الفئة و الطريقة الثانية )و يه موجزة أكرث( يه اس تعامل حنو الطرائق: و يف هذا الاس تخدام للتنويت اكن اس تدعيت الطريقة عليه و اذلي سيسمى موضوع الطريقة هو ما تبىن لجهل الطريقة. print_time هو امس الطريقة أما فقد م ررت >>> start.print_time() 09:45:00 start هو امس الطريقة )مرة أخرى( و هو الاكئن اذلي "املوضوع" متاما مثلام أن املبتدأ يف مجةل امسية هو ما تبىن لجهل امجلةل. فان print_time و بداخل الطريقة يعني املوضوع اىل الربمرت الاول ذلكل هنا عينت.time اىل start و ما أمجع عليه هو أن يسمى أول برمرت يف الطريقة self ذلكل س يكون أقرب اىل الشائع أن تكتب print_time اكلتايل: class Time(object): def print_time(self): print '%2d:%2d:%2d' % (selfhour, selfminute, selfsecond) السبب وراء هذا الاجامع اكن اس تعارة مضنية: حنو النداء لالقرتان print_time اليك هذا الاكئن ليك تطبعه". print_time(start( يويح بأن الاقرتان هو الفاعل فهيي تقول شيئا ك "اي تكون الاكئنات يف الربجمة اكئنية املنحى فاعالت, فاس تدعاء طريقة مثل startprint_tim)( كهنا "اي
start اطبع نفسك". فكر بايثون 152 هذا التغري يف وهجة النظر قد يكون مؤداب لكن الفائدة العملية منه غري واحضة ففي الامثةل اليت رأيناها حىت الان ل فائدة ترى منه. لكن ابعاد املس ئولية عن الاقرتان و الصاقها ابلاكئن قد ميكننا من كتابة اقرتاانت متنوعة أحياان و تسهل صيانة و اعادة اس تخدام النصوص الربجمية. مترين 17.1 أعد كتابة time_to_int من القسم 16.4 ليصبح طريقة. قد ل يكون من الالئق اعادة كتابة int_to_time اىل طريقة مفا هو الاكئن اذلي ستس تدعيه عليه # inside class Time: مثال اخر 17.3 هذه نسخة من increment )من القسم 16.3( اعيدت كتابهتا كطريقة: def increment(self, seconds): seconds += self.time_to_int() return int_to_time(seconds) يف هذه النسخة يفرتض أن ليس معد ل. time_to_int و اس تدعاء increment يكون اكلتايل: يعني ك تبت كطريقة كام يف املثال )17.1( و لحظ أيضا أن الاقرتان حبت و >>> start.print_time() 09:45:00 >>> end = start.increment(1337) >>> end.print_time() 10:07:17 الاكئن increment اىل الربمرت self و تعني القرينة 1337 اىل الربمرت الثاين.seconds قد تكون هذه الالية معقدة خصوصا عند وجود خطأ. مفثال ان اس تدعيت increment بقرينتني س تحصل عىل: >>> end = start.increment(1337, 460) TypeError: increment() takes exactly 2 arguments (3 given) و رساةل اخلطأ هذه حمرية أيضا لوجود قرينتني بني القوسني. لكن علينا الانتباه بأن املوضوع هو أيضا قرينة مما جيعل القرائن ثالثة. مثال معقد أكرث 17.4 is_after من المترين 16.2 معقد أكرث قليال لهنا تأخذ اكئين الربمرت الاول self و الثاين : other Time كربمرتات. يف هذه احلاةل مت الاجامع عىل تسمية # inside class Time: def is_after(self, other): return self.time_to_int() > other.time_to_int() و لس تعامل هذه الطريقة عليك اس تدعاؤها عىل أحد الاكئنني و أن مترر الاخر كقرينة:
فكر بايثون 153 >>> end.is_after(start) True. امجليل يف هذا النحو هو أنه ي قرأ اكللغة الطبيعية: start" "end is after 17.5 طريقة الاكمل هو اكلتايل: طريقة init )اختصار ل init initialization init )خطان سفليان مث init هتيئة( يه طريقة فريدة ت س تدعى عندما يس هتل الاكئن. و امسها مث خطان سفليان أخران(. طريقة init لاكئن Time ستبدو # inside class Time: def init (self, hour=0, minute=0, second=0): self.hour = hour self.minute = minute self.second = second Self.hour = hour >>> time = Time() >>> time.print_time() 00:00:00 >>> time = Time (9) >>> time.print_time() 09:00:00 و من الشائع أن يكون لربمرتات init نفس أسامء اخلصال. هذه العبارة: ختزن قمية الربمرت hour كخصةل ل.self الربمرتات اختيارية فان انديت Time بدون قرائن س تحصل عىل القمية الافرتاضية: ان أعطيت قرينة واحدة ستتجاوز :hour و ان أأعطيت قرينتني ستتجاوز >>> time = Time(9, 45) >>> time.print_time() 09:45:00 :minute و hour و ان أعطيت ثالثة قرائن ستتجاوز القمي الافرتاضية الثالثة مترين 17.2 اكتب طريقة init للفئة Point تأخذ x و y كربمرتات اختيارية و عيهنام للخصلتني املقابلتني هلام.
طريقة 17.6 str طريقة str يه أيضا طريقة خصوصية مثل مفثال هذه يه طريقة str فكر بايثون 154 init للاكئن :Time و املفرتض مهنا ارجاع حمارف متثل الاكئن. # inside class Time: def str (self): return '%2d:%2d:%2d' % (self.hour, self.minute, self.second) و عندما تطبع اكئنا فان ابيثون يس تدعي طريقة :str عندما أكتب فئة جديدة فغالبا ما أبدأ بكتابة عالج الاخطاء. >>> time = Time(9, 45) >>> print time 09:45:00 str init لهنا تساعدين يف هتيئة الاكئنات مث املفيدة يف 17.7 التحميل الزائد للمؤثرات مع تعريف طرق خاصة أخرى فانك حتدد سلوك املؤثرات عىل امناط املس تخدم مفثال ان عرفت طريقة امسها لفئة Time فس ميكنك اس تخدام املؤثر + عىل اكئنات.Time و هذا ما قد يبدو عليه التعريف: و هنا كيفية اس تخدامك هل: عندما تطبق املؤثر + يف اكئنات Time فان ابيثون يس تدعي str اذن فهناك الكثري خلف هذه الكواليس! add # inside class Time: def add (self, other): seconds = selftime_to_int() + othertime_to_int() return int_to_time(seconds) >>> start = Time(9, 45) >>> duration = Time(1, 35) >>> print start + duration 11:20:00 add و عندما تطبع النتيجة يس تدعي ابيثون تغيري سلوك املؤثر ليعمل عىل أمناط املس تخدم يسمى التحميل الزائد overload للك مؤثر يف ابيثون يوجد طريقة خاصة ملزيد من التفاصيل أنظر مثل add.http://doc.spython.org/2/reference/datamodel.html#specialnames مترين 17.4 اكتب طريقة add لفئة.Point
17.8 اليفاد عىل أساس المنط لقد أضفنا يف القسم السابق اكئين Time غري أنك قد تود اضافة عدد حصيح أيضا اىل add_time مث تس تدعي اما other تفحص منط add يأخذ الاقرتان اجلاهز ان اكنت other يه اكئن رمق و ستس تدعي طرق بناءا عىل أمناط القرائن. فكر بايثون 155 اكئن.Time أو :increment التايل هو نسخة من # inside class Time: def add (self, other): if isinstance(other, Time): return self.add_time(other) else: return self.increment(other) def add_time(self, other): seconds = self.time_to_int() + other.time_to_int() return int_to_time(seconds) def increment(self, seconds): seconds += self.time_to_int() return int_to_time(seconds) isinstance Time.increment هنا مثال يس تخدم املؤثر + مع منطني خمتلفني: قمية و اكئن فئة مث يرجع True ان اكنت القمية يه جتلية للفئة. فان add ستس تدعي add_time و ال فاهنا س تفرتض بأن الربمرت هو هذه العملية تسمى الايفاد عىل أساس المنط لهنا توفد العملية احلوسبية اىل عدة هذا التطبيق للطريقة ليس تبادليا للسف فان اكن العامل الاول عدد حصيح س تحصل عىل: >>> start = Time(9, 45) >>> duration = Time(1, 35) >>> print start + duration 11:20:00 >>> print start + 1337 10:07:17 >>> print 1337 + start TypeError: unsupported operand type(s) for +: 'int' and 'instance' Time املشلكة يه أنه بدل من الطلب اىل اكئن أن يضيف عددا فان ابيثون يطلب اىل العدد الصحيح أن يضيف اكئن Time و هو ل يعرف كيف يطلبه الا أن هناكل حل ذيك لهذه املشلكة: الطريقة اخلصوصية radd و تعين add( )right-side تس تدعى هذه الطريقة عندما يكون موقع اكئن Time اىل ميني املؤثر +. و هذا هو تعريفها: # inside class Time: def radd (self, other): return self add (other) >>> print 1337 + start 10:07:17 Point و توبل: و تس تخدم هكذا: مترين 17.5 أكتب طريقة add للنقاط تعمل عىل لك من اك نئ
فكر بايثون 156 ان اكن العامل الثاين Point فعىل الطريقة ارجاع Point جديدة احداثهيا السيين هو مجموع الاحداثيات الس ينية للعوامل و كذكل ابلنس بة لالحداثيات الصادية. ان اكن العامل الثاين توبل فعىل الطريقة اضافة العنرص الاول من التوبل اىل الاحدايث السيين و العنرص الثاين اىل الاحدايث الصادي مث ترجع Point جديدة مع النتيجة. تعدد الاشاكل 17.9 الايفاد عىل أساس المنط مفيد عندما يكون رضوراي لكن )حلسن احلظ( ليس رضوراي دامئا. فميكنك دوما جتنبه عن طريق كتابة اقرتاانت تعمل بشلك حصيح مع القرائن من خمتلف الامناط. فالكثري من الاقرتاانت اليت كتبناها للمحارف تعمل مع خمتلف التسلسالت مثال يف القسم حلساب عدد مرات ظهور حرف يف لكمة: 11.1 histogram س يعمل هذا الاقرتان مع القوامئ و التوبل و حىت مع القواميس طاملا اكنت عنارص مكفاتيح يف d: اس تخدمنا def histogram(s): d = dict() for c in s: if c not in d: d[c] = 1 else: d[c] = d[c]+1 return d s تقطيعية لماكنية اس تخدام العنارص >>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam'] >>> histogram(t) {'bacon': 1, 'egg': 1, 'spam': 4} الاقرتاانت اليت تعمل مع خمتلف الامناط تسمى متعددة الاشاكل.polymorphic ميكن ملتعددات الاشاكل تسهيل اعادة اس تخدام النصوص الربجمية. مثال الاقرتان اجلاهز sum اذلي جيمع عنارص تسلسل سيعمل طاملا اكنت عنارص التسلسل تدمع امجلع. و مبا أن اكئنات Time تزودان بطريقة add فس تعمل مع :sum >>> t1 = Time(7, 43) >>> t2 = Time(7, 41) >>> t3 = Time(7, 37) >>> total = sum([t1, t2, t3]) >>> print total 23:01:00 اجامل ان اكنت مجيع العمليات داخل اقرتان تعمل مع منط ما فالقرتان نفسه يعمل مع ذكل المنط. أفضل أنواع متعددات الاشاكل يه تكل تأيت ابلصدفة عندما تكتشف بأن الاقرتان اذلي كتبته يعمل عىل منط مل تفكر فيه أبدا.
17.10 متر الخطاء عالج فكر بايثون 157 من اجلائز اضافة خصال لاكئن يف أي مرحةل من مراحل تنفيذ الربانمج لكن ان كنت من املؤمنني بنظرية المنط فسيصبح وجود اكئنات من نفس المنط لها مجموعات خمتلفة من اخلصال أمرا مشكواك فيه دليك. يف العادة ينصح بهتيئة مجيع خصال الاكئن يف طريقة.init ان مل تكن متأكدا من أن اكئن ما هل تكل اخلصةل فاس تخدم الاقرتان اجلاهز hasattr )انظر القسم 15.7(. سبيل اخر للوصول اىل خصال اكئن يه اس تخدام اخلصةل اخلصوصية أسامء اخلصال )مكحارف( و بني القمي: و لعالج الخطاء قد يفيدك ابقاء هذا الاقرتان يف متناول يدك: dict و يه عبارة عن قاموس يوفق بني >>> p = Point(3, 4) >>> print p dict {'y': 4, 'x': 3} def print_attributes(obj): for attr in obj dict : print attr, getattr(obj, attr) print_attributes بعنارص قاموس الاكئن و تطبع لك خصةل و القمية املرادفة لها. الاقرتان اجلاهز getattr يأخذ اكئنا و امس خصةل )مكحارف( و يرجع قمية اخلصةل. 17.11 واهجة املس تخدم و التطبيق ابقاء انصية الربجميات ممسوكة هو أحد أهداف الربجمة اكئنية املنحى يعين هذا أن الربانمج س يظل يعمل حىت عندما تتغري أج زءا النظام الاخرى و أيضا عند تعديل الربانمج ليك يوافق ما يس تجد من املتطلبات. من مفاهمي التصممي اليت تساعد عىل حتقيق هذا الهدف هو ابقاء واهجة املس تخدم منفصةل عن التطبيق. و يعين هذا ابلنسبة للاكئنات أن تس تقل الطرق اليت توفرها الفئات عن كيفية متثيل اخلصال. مثال طوران يف هذا الفصل فئة لمتثيل الوقت الطرق اليت توفرها هذه الفئة تتضمن time_to_int.add_time و is_after و ميكننا تطبيق هذه الطرائق بعدة أساليب. و تفاصيل هذا التطبيق يعمتد عىل كيفية اظهار الوقت اليت نفضلها. اكنت خصال اكئن Time يف هذا الفصل يه hour و minute و.second كبديل لها اكن بوسعنا استبدال لك هذه اخلصال بعدد حصيح واحد ميثل عدد الثواين اليت مرت منذ منتصف الليل. سيسهل هذا التطبيق كتابة بعض الطرق مثل is_after لكنه سيصعب الاخرى. قد تكتشف بعد أن تطلق فئة جديدة أن هناك تطبيقا أفضل. ان اكنت هناكل أجزاء أخرى يف برانجمك تس تخدم هذه الفئة فس يكون تغيري الواهجة استنفاذا للوقت و منبعا للخطاء. لكن ان كنت مصمت الواهجة بعناية فستمتكن من تغيري التطبيق بدون احلاجة اىل تغيري الواهجة مما يعين أنه ل حاجة لتغيري أجزاء أخرى يف الربانمج. مما يعنيه فصل واهجة املس تخدم عن التطبيق هو اخفاء املعلومات. فالنصوص الربجمية يف املواقع الاخرى من الربانمج )خارج
فكر بايثون 158 تعريف الفئة( جيب أن تس تخدم الطرق لقراءة و تعديل حاةل الاكئن فقط ل للوصول اىل خصاهل. مترين 17.6 محل النص الربجمي لهذا الفصل من.http://thinkpython.com/code/Time2.Py غري خصال Time لتصبح عددا حصيحا واحدا ميثل الثواين منذ منتصف الليل. مث عدل الطرق ( و كذكل الاقرتان )int_to_time ليعمل مع التطبيق اجلديد. سيتوجب عليك تعديل النص الاختباري يف main و عندما تنهتيي جيب أن تكون اهلرجات كام اكنت يف السابق. احلل:.http://thinkpython.com/code/Time2_soln.py املعاين 17.12 لغة اكئنية املنحى :object -oriented language لغة برجمة توفر مزااي مثل فئات املس تخدم و حنو للطرق لتسهيل الربجمة اكئنية املنحى. الربجمة اكئنية املنحى :object-oriented programming أسلوب يف الربجمة تكون فيه البياانت و العمليات علهيا منظمة يف فئات و طرائق. طريقة :method اقرتان معرف داخل فئة يس تدعى عىل جتليات لتكل الفئة. موضوع :subject الاكئن اذلي تس تدعى عليه الطريقة. التحميل الزائد للمؤثر :operator overloading تغيري سلوك املؤثر )مثل +( حبيث يعمل مع منط أوجده املس تخدم. الايفاد عىل أساس المنط :type-based dispatch قالب برجمي يفحص منط املؤثر و يس تدعي الاقرتاانت اهلتلفة عىل الامناط اهلتلفة. متعدد الاشاكل :polymorphic صفة لالقرتان اذلي يعمل مع أكرث من منط. اخفاء املعلومات :information hiding مبدأ أن واهجة املس تخدم اليت يوفرها الاكئن جيب أل تعمتد تطبيقه خصوصا متثيل خصاهل. 17.13.1.2.3 متارين مترين 17.7 هذه الامترين عبارة عن قصة حتذيرية عن أكرث الخطاء ش يوعا و الصعب يف العثور علهيا يف ابيثون. اكتب فئة امسها kangaroo هبا الطرق التالية: اخترب نصك باكئين كيس kanga طريقة init هتي خصةل امسها pouch_contents اىل قامئة فارغة طريقة امسها put_in_pouch تأخذ اكئنا من أي منط و تضيفه طريقة str ترجع متثيال حمارفيا للاكئن kangaroo و نلتوايت )= pouch كيس( اىل pouch_content kangaroo معينا اايهام اىل متغريين امسهام roo و kanga محل.http://thinkpython.com/code/BadKangaroo.py اذلي به حل املسأةل السابقة و به أيضا بقة كبرية مقيتة! اعرث علهيا و صلحها مث بعدها أضف roo اىل حمتوايت
ان استسلمت ميكنك حتميل رشح املشلكة و حلها من:.http://thinkpython.com/code/GoodKangaroo.py فكر بايثون 159 مترين 17.8 يزود مديول ابيثون Visual رسوم ثالثية الابعاد. و هو ليس دامئا من مضن تنصيب ابيثون و عليه فقد يتطلب الامر حتميهل من مس تودع الربامج دليك و ال مفن.http://vpython.org املثال التايل خيلق فضاءا ثاليث الابعاد طوهل 256 مديول و كذكل عرضه و ارتفاعه و جيعل النقطة )128, 128( 128 املركز "center" مث يرمس كرة زرقاء. from visual import * scenerange = (256, 256, 256) scenecenter = (128, 128, 128) هنا عبار عن توبل من color = (0.1, 0.1, 0.9) # mostly blue sphere(pos=scenecenter, radius=128, color=color) RGB أي أن عنارص التوبل يه R و G و B و مس توايهتا بني 0.0 و 1.0 )أنظر color.http://en.wikipedia.org/wiki/rgb_color_model ان شغلت هذا النص فيجب أن ترى انفذة خبلفية سوداء و هبا كرة زرقاء. و ان جررت الزر الاوسط فستمتكن من تكبري الصورة و تصغريها ميكنك أيضا تدوير الكرة ابجلر ابلزر الامين لكنك لن تلحظ الفرق لن هناك كرة واحدة يف هذا الكون. توجد احللقة التالية مكعبا من الكرات: t = range(0, 256, 51) for x in t: for y in t: for z in t: pos = x, y, z sphere(pos=pos, radius=10, color=color).1.2.3 ضع هذا النص يف برانمج و تأكد من أنه يعمل عدل الربانمج حبيث يصبح للك كرة اللون اذلي يناسب موقعها يف الفراغ RGB انتبه لكون الاحداثيات يه يف املال 255-0 و RGB يه يف املال 0.0 و 1.0. محل و اس تخدم الاقرتان read_colors لتنشئ قامئة ابللوان املتاحة يف نظام التشغيل دليك تكون هبا أسامء الالوان و قميها و للك لون مسمى. ارمس دائرة يف املاكن اذلي يقابل قمية.RGB ميكنك الاطالع عىل حيل عىل.http://thinkpython.com/code/color_space.py
فكر بايثون 160 الفصل الثامن عرش التوريث سأقدم يف هذا الفصل فئات متثل أوراق اللعب و شدات و فت ات بوكر. ان كنت ل تلعب البوكر فاقرأ عهنا هنا.http://en.wikipedia.org/wiki/Poker لكن ليس عليك أن تتعلمها فسأقول كل ما اذلي س تحتاجه مهنا يف هذه الامترين أمثةل النصوص الربجمية لهذا الفصل متوفرة من.http://thinkpython.com/code/Card.py ان مل تكن عىل معرفة بأوراق اللعب فباماكنك الاطالع عىل :.http://en.wikipedia.org/wiki/playing_cards 18.1 اكئنات البطاقات هناكل اثنتان و مخسون بطاقة لعب يف الشدة و لك مهنا ينمتي اىل واحد من الاربعة أشاكل و اىل واحدة من الثالثة عرش مرتبة. الاشاكل يه البس توين Spades و الكبة Hearts و ادليناري Diamonds و الس بايت Clubs )مرتبة تنازليا حسب لعبة بردج(. مث هناك املراتب و يه: الص 10-9-8-7-6-5-4-3-2 مث الودل Jack و البنت Queen و الشيخ.King و الص قد يكون أعىل من الش يخ مرتبة أو أقل من 2 عىل حسب اللعبة اليت تلعهبا. ان أردان تعريف اكئن جديد لمتثيل بطاقات اللعب مفن الواحض أن خصاهل س تكون: rank و suit )مرتبة و شلك( لكن اختيار منط اخلصال ليس واحضا اكخلصال نفسها. أحد الاحامتلت هو اس تخدام حمارف هبا لكامت ك Spade للشاكل و Queen للمراتب. لهذا الاحامتل مشالك احداها صعوبة مقارنة البطاقات لرنى أهيا أعىل مرتبة أو شالك. طريقة بديةل يه اس تخدام الاعداد الصحيحة لرتمزي املراتب و الاشاكل. الرتمزي هنا يعين أننا س نخطط بني الارقام و الاشاكل أو بني الارقام و املراتب. ليس املقصود هبذا النوع من الرتمزي الرسية ( و ال سنسميه تشفريا(. عىل سبيل املثال يظهر اجلدول التايل الاشاكل و الاعداد الصحيحة املقابةل لها: Spades 3 Hearts 2 Diamonds 1 Clubs 0 هذا الرتمزي يسهل علينا مقارنة البطاقات لن الشلك الاعىل يقابهل عدد أكرب فميكننا مقارنة الاشاكل مبقارنة ما يرمز الهيا.
فكر بايثون 161 التخطيط للمراتب واحض مبا فيه الكفاية رمق لك بطاقة سريمز للعدد الصحيح اذلي ميثهل و للصور: Jack 11 Queen 12 King 13 اس تخدمت الشلك ليك أقول بأن هذه التخطيطات ليست جزءا من ابيثون. بل جزء من تصممي الربامج و يه ل تظهر رصحية يف النصوص الربجمية. تعريف الفئة ل Cards سيبدو اكلتايل: و اكلعادة تأخذ طريقة init برمرت اختياري للك خصةل و الافرتاي هو 2 للس بايت و ليك تنشئ بطاقة عليك نداء Card مع شلك و مرتبة البطاقة اليت تريدها class Card(object): """Represents a standard playing card""" def init (self, suit=0, rank=2): self.suit = suit self.rank = rank queen_of_diamonds = Card(1, 12) خصال الفئة 18.2 ليك نطبع اكئن البطاقة ابلشلك اذلي يقرأه الناس بسهوةل علينا التخطيط من الرتمزي العددي اىل املرتبة و الشلك املقابلني هل من الطبيعي أن يكون السبيل اىل ذكل قوامئ من انلارف. تعني تكل القوامئ اىل خصال فئة: املتغريات مثل لهنا ترتبط باكئن الفئة و # inside class Card: suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades'] rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King'] def str (self): return '%s of %s' % (Card.rank_names[self.rank], Card.suit_names[self.suit]) rank_names suit_names.card املصطلح يفرق بني متغريات مثل rank و suit املعرفة داخل الفئة لكن ليس داخل أي طريقة تسمى خصال الفئة و اليت تسمى خصال التجليات لهنا ختتص بتجلية بعيهنا. الك النوعني من اخلصال يكون الوصول الهيام ابلتنويت مثال str فهيا self اكئن بطاقة و self.rank يه مرتبة البطاقة و بنفس الطريقة فان Card هو اكئن بطاقة و Card.rank_names يه قامئة ابنلارف املتعلقة هبذه الفئة. و للك فئة suit و rank ختصها لكن هناك نسخة واحدة فقط من suit_names و من rank_names
فكر بايثون 162 الشلك 18.1 رمس الاكئن أن وضعنا لك هذه العبارات معا Card.rank_names[self.rank[ ستعين "اس تخدم اخلصةل للاكئن self مكؤرش يف قامئة rank_names من الفئة Cards مث اخرت انلارف املناسبة" rank العنرص الاول من rank_names يكون حنصل عىل توجيه هل مزية مجيةل و يه أن املؤرش 2 اس تخدام قاموس بدل من قامئة. None ابلطرائق اليت دلينا حىت الان ميكننا خلق و طباعة البطاقات: لعدم وجود بطاقة مرتبهتا صفر. ابدراج None كحارس عىل مزنةل يوجه اىل انلارف 2 و هكذا. لتجنب فركة كهذه اكن يتوجب علينا >>> card1 = Card(2, 11) >>> print card1 Jack of Hearts 18.3 مقارنة البطاقات هناكل مؤثرات نسبية للمناط اجلاهزة )<, <, == اخل( تقارن بني القمي و تقرر اذا ما اكنت احداها أكرب أو أصغر أو تساوي الاخرى. ابلنس بة لمناط املس تخدم ميكننا ختطي السلوك الاصيل لهذه املؤثرات ابس تخدام طريقة تدعى cmp تأخذ cmp برمرتين الثاين أكرب و صفرا ان تساوا. self و other مث ترجع رمقا موجبا ان اكن الاكئن الول أكرب من الثاين و سالبا اكن الرتتيب الصحيح للبطاقات غري واحض مثال أهيا أفضل: 3 س بايت أم 2 ديناري فواحد مهنا أعىل مرتبة لكن الثاين أعىل شالك. اذن للمقارنة بني البطاقات عليك أن حتدد ما هو الامه املرتبة أم الشلك. قد تعمتد الاجابة عىل أي لعبة تلعب لكن لنبسط المور و نقول بأن الشلك هو المه اذن فلك البس توين أعىل مرتبة من من لك ادليناري و هكذا. أما و قد اس تقرينا عىل هذا الرتتيب فميكننا الان كتابة # inside class Card: : cmp def cmp (self, other): # check the suits if self.suit > other.suit: return 1 if self.suit < other.suit: return -1 # suits are the same... check ranks if self.rank > other.rank: return 1 if self.rank < other.rank: return -1
فكر بايثون 163 # ranks are the same... it's a tie return 0 # inside class Card: ميكن كتابة نفس النص لكن ابجياز ابس تخدام مقارانت توبل: def cmp (self, other): t1 = self.suit, self.rank t2 = other.suit, other.rank return cmp(t1, t2) لالقرتان اجلاهز cmp نفس واهجة الطريقة اكنت الثانية أكرب و صفر ان تساوات. cmp : يأخذ قميتني و يرجع رمقا موجبا ان اكنت الاوىل أكرب و سالبا ان يف ابيثون 3 اختفت طريقة cmp و كذكل cmp ذلا عليك استبدالها ب self أصغر من other ابماكنك تطبيق lt ابس تخدام توبل و مؤثر > )أصغر( lt اليت ترجع ان اكنت True مترين 18.1 أكتب طريقة cmp لاكئنات.Time تلميح: ميكنك اس تخدام مقارنة توبل لكن ميكنك الاخذ ابلعتبار اس تخدام طرح العداد الصحيحة. الشدات 18.4 الان و قد أصبح دلينا بطاقات اللعب Cards حان الوقت لتعريف الشدات.Decks مبا أن الشدة مكونة من بطاقات مفن الطبيعي أن حتتوي لك شدة عىل قامئة من البطاقات كخصةل. التايل هو تعريف فئة.Deck توجد طريقة init اخلصةل cards و توجد مجموعة الثنني و مخسني بطاقة المنوذجية : class Deck(object): def init (self): self.cards = [] for suit in range(4): for rank in range(1, 14): card = Card(suit, rank) self.cards.append(card) أسهل طريقة ملاكثرة الشدة يه اس تخدام حلقة عش ية. ترمق احللقة اخلارجية الاشاكل من 0 اىل 3 احللقة ادلاخلية ترمق املراتب من 1 اىل 13. لك تكرار يوجد بطاقة جديدة مع املرتبة و الشلك مث تضمها اىل self.cards
فكر بايثون 164 #inside class Deck: 18.5 هاك طريقة طباعة البطاقات str للشدة: def str (self): res = [] for card in self.cards: res.append(str(card)) return '\n'.join(res) ترشح هذه الطريقة اسلوب فعال ملرامكة انلارف الكبرية: بناء قامئة من انلارف مث اس تخدام.join الاقرتان اجلاهز str ينادي الطريقة str عىل لك بطاقة و يرجع حمارف متثلها. مبا أننا اس تدعينا join عىل حمارف سطر جديد فس ت فصل البطاقات بسطر جديد. هكذا ستبدو النتيجة: حىت و ان بدت النتيجة ك 52 سطرا فهيي ل تزال حمارف طويةل واحدة حتتوي عىل سطور جديدة. >>> deck = Deck() >>> print deck Ace of Clubs 2 of Clubs 3 of Clubs... 10 of Spades Jack of Spades Queen of Spades King of Spades أضف 18.6 احذف اخلط و رتب لبد للتعامل مع بطاقات اللعب من طريقة متكنك من حسب بطاقات من الشدة و اعادهتا متنحنا الطريقة مقبوةل لهذه املهمة: طريقة pop #inside class Deck: def pop_card(self): return self.cards.pop() مبا أن pop تسحب اخر بطاقة يف القامئة فاننا نتعامل مع الشدة من السفل. يعترب حسب البطاقات من الاسفل غشا )فت من حتت( لكن يف هذا الس ياق فهو جائز. لضافة بطاقات سنس تفيد #inside class Deck: def add_card(self, card): self.cards.append(card) من :append هكذا اقرتاانت تس تخدم اقرتاانت اخرى دون القيام بأي معل بنفسها تسمى يف الجنلزيية قرشة و أصلها من النجارة حيث تكىس الطبقة اخلارجية من رخيص اخلشب بأخرى من مثينه. )يف انبلس قرشة: حناس مطيل ابذلهب(. حنن هنا نعر ف طريقة واهنة للتعبري عن معلية عىل قامئة من التعبريات اليت تناسب الشدات. مكثال اخر ميكننا كتابة طريقة شدة امسها shuffle تس تخدم الاقرتان shuffle من مديول : random
فكر بايثون 165 ل تنس اس ترياد. random # inside class Deck: def shuffle(self): random.shuffle(self.cards) مترين 18.2 اكتب طريقة شدة امسها sort تس تخدم الطريقة sort طريقة cmp اليت عرفناها لتحديد كيفية الرتتيب. لرتتيب البطاقات يف deck.sort ابس تخدام التوريث 18.7 أكرث اخلصائص اللغوية تعلقا ابلربجمة اكئنية املنحى يه التوريث. التوريث يه القابلية لتعريف فئة جديدة تكون نسخة معدةل من فئة موجودة أصال. مسيت "توريثا" لن الفئة اجلديدة ترث طرائق اللغة املوروثة. و ملد هذا التشبيه اىل أقصاه فاملو رث يسمى اب و الوارث يسمى ابن. لتوضيح هذا املفهوم لنقل أنك تريد فئة تسمى فت ة.hand و يه البطاقات اليت حيملها الالعب يف يده. الفتة مثلها مثل الشدة الكهام يقوم عىل مجموعة من البطاقات و الكهام حباجة اىل معليات اكضافة و حذف البطاقات. لكن الفتة ختتلف عن الشدة أيضا فهناك معليات نريد أن نقوم هبا عىل الفتة لكهنا بال معىن للشدة مثال ميكننا يف البوكر مقارنة فتتني لرن أهيام سرتحب. يف الربدج ميكننا حساب احامتلت الرحب لفتة ما لجل املراهنة. وصف العالقة بني الفئات )متشاهبة لكن ابختالف( ينطبق عىل التوريث. تعريف الفئة الابن كتعريف أي فئة أخرى عدا عن أن الفئة الب تكون بني قوسني: class Hand(Deck): """Represents a hand of playing cards""" يشري هذا التعريف اىل أن.Decks و كذكل Hands ترث من hand deck مما يعين أنه ابماكننا اس تخدام طرائق مثل و pop_card رمغ أن Hand ترث أيضا init من Deck ال أهنا يف احلقيقة ل تفعل ما نريدها أن تفعل: فبدل من اكثار الفتة ابل 52 بطاقة جديدة عىل طريقة init للفتات هتيئة cards بقامئة فارغة. ان زودان الفئة بطريقة Hand init ستتخطى تكل اليت يف فئة # inside class Hand: : Deck def init (self, label=''): self.cards = [] self.label = label >>> hand = Hand('new hand') >>> print hand.cards [] >>> print handlabel اذن فعندما تنشئ فتة سيس تدعي ابيثون طريقة :init
فكر بايثون 166 ال أن طرق أخرى قد و رثت عن new hand Deck اذن فميكننا اس تخدام pop_card من الطبيعي أن تكون اخلطوة التالية يه كبسةل هذا النص يف طريقة و لت س مى تأخذ و add_card للفت: >>> deck = Deck() >>> card = deck.pop_card() >>> hand.add_card(card) >>> print hand King of Spades :move_cards #inside class Deck: def move_cards(self, hand, num): for i in range(num): hand.add_card(self.pop_card()) hand self move_cards قرينتني: اكئن Hand.None و عدد البطاقات للفت و عىل و تعدل و ترجع يف بعض الالعاب تنتقل البطاقات من يد لعب اىل يد اخر و أحياان من يد الالعب اىل الشدة. ميكنك اس تخدام hand و ميكن ل Hand و أن تكون Deck أن تكون self لي من هذه احلالت: فميكن ل move_cards )بغض النظر أن الامس يعين فتة( أن تكون شدة.Deck مترين 18.3 أكتب طريقة Deck )شدة( و مسها deal_hands تأخذ برمرتين عدد الفتات و عدد البطاقات يف لك فتة مث تنشئ اكئن Hand جديد مث تفت عدد الكروت املناسب يف لك فتة مث ترجع قامئة باكئنات.Hand التوريث خاصية مفيدة. فنصوص بعض الربامج اليت ت ك رر العمل تصبح أكرث أانقة مع التوريث. التوريث يسه ل اعادة اس تخدام النصوص الربجمية بسبب اماكنية هتذيب سلوك الفئات الابء لتفي مبتطلباتك دون احلاجة اىل تعديلها. و يف بعض الاحيان يعكس بناء التوريث البناء الطبيعي للمشلكة مما جيعل الربانمج أسهل للفهم. الا أنه من انحية اثنية فالتوريث قد جيعل قراءة الربامج أصعب. فعند اس تدعاء طريقة يكون من غري الواحض أحياان أين ميكن العثور عىل تعريفها فالنص املتعلق هبا قد يكون متفرقا يف عدة مديولت. مث ان الكثري من الاش ياء اليت ميكن معلها ابلتوريث ميكن معلها بدونه و أحياان تكون أفضل بدونه. رمس الفئة 18.8 لقد رأينا حىت الان الرمس املستف اذلي يبني حاةل الربانمج و رمس الاكئن اذلي يبني خصال الاكئن و قميها. متثل تكل الرسومات نلة حلظية من تنفيذ الربانمج ذلكل فهيي تتغري دامئا خالل معل الربانمج. تكل الرسومة مفصةل جدا و لهداف معينة يبالغ يف التفصيل رمس الفئة يف املقابل يكون متثيال خمترصا لبناء الربانمج فبدل من اظهار الاكئنات املنفردة يظهر الفئات و العالقة بيهنا. الشلك 18.2: رمس الفئة
فكر بايثون 167 هناكل عدة أنواع من العالقات بني الفئات: اكئنات داخل فئة هبا مرجعيات لاكئنات يف فئة أخرى مثال لك Rectangle حيتوي عىل مرجع ل Point و لك Deck حيتوي عىل مراجع لعدة Card هذه العالقات تسمى HAS-A أي ( a a Rectangle has.)point قد ترث احدى الفئات من أخرى و هذه العالقة تسمى IS-A أي Deck( a(. Hand is a kind of قد تعمتد احدى الفئات عىل الاخرى من انحية أن التغيري عىل واحدة يتطلب تغيريا عىل الفئة الاخرى. رمس الفئة هو متثيل تصويري لتكل العالقات مثال الشلك 18.2 يظهر العالقة بني Card و Deck و.Hand السهم ذو الرأس املثلث املفرغ ميثل عالقةIS-A و يف هذه احلاةل يعين أن Hand ترث من.Deck السهم العادي ميثل عالقة HAS-A و يف هذه احلاةل فان دلى Deck مرجاع لاكئنات.Card النجمة * قرب السهم للتكرار فهيي تقول لنا عدد البطاقات يف الشدة و قد يكون التكرار رمق عادي مثل 52 أو نطاقا ك 5...7 أو قد تكون جنمة * و اليت تعين بأنه ميكن أن يكون للشدة أي عدد من البطاقات. الرسوم املفصةل أكرث قد حتتوي عىل قامئة ابلبطاقات لكن يف العادة ل تضاف الامناط اجلاهزة يف رسوم الفئات. مترين 18.4 اقرأ TurtleWorld.py و World.py و Gui.py مث أرمس رمس فئة يوحض العالقة بيهنا الخطاء عالج 18.9 قد جيعل التوريث من عالج طريقة ست س تدعى. الخطاء عرص مخ حقيقي. لنك عندما تس تدعي طريقة عىل اكئن فأنت ل تعمل ابلضبط أي افرض أنك تكتب اقرتاان يعمل مع اكئنات.Hand سرتيد العمل مع اكفة أنواع الفتات كفتة البوكر و الربدج...اخل. ان اس تدعيت طريقة ك shuffle فقد حتصل عىل تكل الطريقة املعرفة يف Deck لكن أن ختطت أي من الفئات الفرعية هذه الطريقة فس تحصل عىل نسخة الطريقة من تكل الفئة. يف لك مرة لتكون متأكدا من رساين تنفيذ برانجمك يكون احلل الابسط هو اضافة عبارة املقصودة. فان طبعت Deck.shuffle الرساةل اليت تقول شيئا مثل فس ميكنك متابعة رساين الربانمج. print أو ميكنك اس تخدام هذا الاقرتان و هو يأخذ اكئنا و طريقة و يرجع الفئة اليت زودت تعريف الطريقة: و هذا مثال: اذن فطريقة يف بداية الطريقة Running Deck.shuffle def find_defining_class(obj, meth_name): for ty in type(obj).mro(): if meth_name in ty dict : return ty >>> hand = Hand() >>> print find_defining_class(hand, 'shuffle') <class 'Card.Deck'> shuffle find_defining_class لهذه ال Hand أتت من.Deck تس تخدم طريقة mro للحصول عىل قامئة باكئنات الفئة )أمناط الفئة( حيث سيبحث
فكر بايثون 168 فهيا عن الطرائق. MRO اختصار.method resolution order اليك اقرتاحا حول تصممي الربانمج: عندما تتخطى طريقة ما فيجب أن تكون واهجة الطريقة اجلديدة يه نفسها واهجة القدمية. و علهيا أخذ نفس الربمرتات و ارجاع نفس الامناط و اتباع نفس الرشوط املس بقة. ان اتبعت هذا املبدأ فسرتى بأن لك اقرتان مصم ليعمل مع جتلية لفئة مثل Deck س يعمل مع جتليات الفئات الفرعية مثل Hand أو.PokerHand و ان خالفت هذا املبدأ فسيهنار النص الربجمي مثل )اسف عىل التعبري( بيت من بطاقات الشدة. كبسةل البياانت 18.10 يف الفصل 16 رشحنا خطة تطوير ميكن تسميهتا ب"التصممي اكئين املنحى" فقد حددان الاكئنات اليت حنتاهجا Time, Point, Rectangle و عرفنا الفئات اليت متثلها. اكن هناك دامئا ما يربط بني الاكئنات و بني يشء عىل أرض الواقع )أو الواقع الرايي(. لكن يف يف بعض الاحيان ل يكون الربط بيهنا و بني الواقع ظاهرا و ل يكون واحضا أي اكئنات تريد و ل كيفية تعاملها مع بعضها. بنفس الطريقة اليت استكتشفنا فهيا واهجات الاقرتاانت عن طريق الكبسةل و التعممي س نكتشف واهجات الفئات عن طريق كبسةل الفئات. حتليل ماركوف من القسم 13.8 مثال ممتازا. ان كنت قدمحلت نيص من.http://thinkpython.com/code/markov.py سرتى بأنه يس تخدم متغريين معوميني suffix_map و prefix تقر أها و تكتهبا عدة اقرتاانت. suffix_map = {} prefix = () و لكون هذه املتغريات معومية فلن نمتكن من اجراء أكرث من حتليل واحد لك مرة. فعندما نقرأ نصني ستضاف البادءات و اللواحق فهيام اىل نفس هيلك البياانت )و اذلي حبد ذاته مصدرا للنصوص املسلية(. ليك جنري أكرث من حتليل و نبقهيا منفصةل ميكننا كبسةل احلاةل للك حتليل يف اكئن. هذا ما سيبدو عليه: class Markov(object): def init (self): self.suffix_map = {} self.prefix = () اخلطوة التاليةيه حتويل الاقرتاانت اىلطرائق مثال هذه :process_word def process_word(self, word, order=2): if len(self.prefix) < order: self.prefix += (word,) return try: self.suffix_map[self.prefix]append(word) except KeyError: # if there is no entry for this prefix, make one self.suffix_map[self.prefix] = [word] self.prefix = shift(self.prefix, word) حتويل الربانمج هبذا الاسلوب -.)4.7 تغيري التصممي بدون تغري الاقرتان هو مثال اخر عىل التفتيت و البناء )انظر القسم
فكر بايثون 169 هذا املثال أوىح لنا خبطة تطوير لتصممي الاكئنات و الطرائق: 1. ابدأ بكتابة الاقرتاانت اليت تقرأ و تكتب املتغريات العمومية )عند الرضورة(. 2. عندما تمتكن من جعل الربانمج يعمل احبث عن ترابطات بني املتغريات العمومية و الاقرتاانت اليت تس تخدهما. 3. كبسل املتغريات املتعلقة باكئن كخصال لهذا الاكئن. 4. حول الاقرتاانت املرتابطة اىل طرائق يف الفئة اجلديدة. مترين 18.5 محل نيص من الفصل.http://thinkpython.com/code/markov.Py 13.8 مث اتبع التعلاميت النف ذكرها لكبسةل املتغريات العمومية كخصال للفئة اجلديدة و اليت س يكون امسها.Markov احلل:.http://thinkpython.com/code/Markov.py املعاين 18.11 ترمزي )رمز( :encode أن متثل مجموعة من القمي ابس تخدام مجموعة قمي أخرى عن طريق الوصل بيهنا. خصةل فئة :Class attribute خصةل ترتبط باكئن فئة تع رف خصال الفئات داخل تعريف الفئة لكن خارج أية طريقة. خصةل جتلية :instance attribute خصةل ترتبط لتجلية لفئة ما. قشورية :veneer طريقة أو اقرتان توفر واهجات خمتلفة لقرتاانت اخرى من دون أن يكون لها معل حوسيب خيصها. التوريث :inheritance القدرة عىل تعريف فئة جديدة تكون نسخة معدةل عن فئة معرفة سابقا. الفئة الاب :parent class الفئة اليت ترث مهنا الفئة الابن. الفئة الابن :child فئة جديدة انشئت ابلوراثة من فئة قامئة تسمى أيضا فئة فرعية. عالقة :IS-A العالقة بني فئة الابناء و فئة الاابء. عالقة :HAS-A عالقة بني فئتني حتتوي جتليات احداها مراجع لتجليات ا لفئة الاخرى. رمس الفئة :class diagram رمس يبني الفئات يف برانمج و العالقات بيهنا. تعدد الاشاكل :multiplicity تنويت يف رمس الفئة يظهر لعالقة HAS-A عدد املراجع اىل جتليات من فئة أخرى. متارين 18.12 مترين 18.6 التايل هو عدد الفتات املتاحة يف لعبة بوكر برتتيب تصاعدي حسب القمية )و تنازليا حسب الاحامتل(: زوجان :pair بطاقتان هلام نفس املرتبة. أربعة أزواج :two pairs أربعة بطاقات لها نفس املرتبة. ثالثة من نوعها :three of a kind ثالثة بطاقات لها نفس املرتبة. مبارش :strait مخس بطاقات متسلسةل املرتبة )الاص ميكن اعتباره أعىل أو أدىن أص 4-3-2- يه 5 straight كذكل 10 -ودل- تنب -ش يخ-أص لكن ل تعترب بنت-ش يخ-صأ -3-2.)straight فلش :flush مخس بطاقات من نفس الشلك. و
ف لهاوس فكر بايثون 170 :full house ثالثة بطاقات من نفس املرتبة و بطاقتان من مرتبة واحدة أخرى..1 فلش مبارش :straight flush مخس بطاقات متسلسةل لكن من نفس الشلك. هدف هذه الامترين هو توقع حسب هذا البطاقات يف الفتات اهلتلفة. 1. محل امللفات التالية من nhttp://thinkpython.com/code :Cards.py نسخة اكمةل من فئات Card و Deck و Hand اليت مرت علينا يف هذا الفصل. :PokerHand.py تطبيق غري مكمتل من فئة متثل فتة بوكر و معها نص برجمي لختبارها. 2. عندما تشغل PokerHand فس يقوم بفتات بوكر من 7 بطاقات و يفحص ان اكن أي مهنا حيتوي عىل فلش اقرأ هذا النص الربجمي بعناية قبل امليض قدما. 3. أضف طرائق ل PokerHand.py و مسها has_pair و has_twopair و هكذا ترجع True أو False حسب موافقة الفتة مع القوانني املقابةل عىل النص أن يعمل مع أي الفتات اليت هبا أي عدد من البطاقات )رمغ أن 5 و 7 يه الفتات الاكرث ش يوعا يف البوكر(. 4. اكتب طريقة امسها classify تكتشف أعىل قمية يف التصنيف و تعدل خصةل label بناءا علهيا مثال فتة 7 بطاقات قد يكون هبا فلش و زوجني اذن جيب أن تسمى فلش. 5. عندما تراتح اىل أن طرائق التصنيف تعمل اخلطوة التالية يه توقع احامتلت الفتات اهلتلفة اكتب اقرتاان يف PokerHand.py خيلط بطاقات شدة و يوزعها عىل فتات مث حييص عدد مرات ظهور التصنيفات. 6. اطبع جدول ابلتصانيف و احامتلهتا شغل الربانمج عدة مرات تزيد فهيا عدد الفتات اىل أن تصبح النتيجة بدقة معقوةل قارن نتاجئك ابلقمي من.http://en.wikipedia.org/wiki/Hand_rankings احلل:.http://thinkpython.com/code/PokerHandSoln.py مترين 18.7 هذا المترين يس تخدم TurtleWorld من الفصل 4 س تكتب برانجما ميكن السلحفاة من لعب اللمسة ان مل تكن تعرفها فاقرأ عن Tag من.http://enwikipediaorg/wiki/Tag_game محل و به ثالثة سالحف ان ضغطت زر.http://thinkpython.com/code/Wobbler.py RUN ستمتىش السالحف عشوائيا. و شغهل سرتى عامل السلحفاة اقرأ النص الربجمي و تأكد من استيعابك لطريقة معهل. ترث فئة Wobbler من Turtle مما يعين أن طرائق Turtle و يه bk( )lt, rt, fd, ستعمل عىل.Wobbler ت س تدعى طريقة step من قبل TurtleWorldو بدورها تس تدعي steer اليت توجه السلحفاة اىل الاجتاه املطلوب و wobble اليت تقوم ابلتفافة عشوائية ابلتناسب مع بالدة السلحفاة و move و اليت حترك السلحفاة اىل الامام بضعة بكسالت حسب رسعهتا. اخلق ملفا امسه Taggerpy اس تورد لك يشء من Wobbler مث عرف فئة امسها Tagger ترث من Wobblerاندي make_wrld ممرا اكئة الفئة Tagger كقرينة. اضف طريقة steer اىل Tagger ليك تتخطى تكل اليت يف.Wobbler كنقطة بداية اكتب نسخة توجه السلحفاة اىل نقطة الاصل دامئا. تلميح: اس تخدم الاقرتان الرايي atan2 و خصال السلحفاة, xو y.heading عدل عىل steer يس تدعي حبيث تظل السلحفاة مضن احلدود. و لعالج مرة واحدة عىل لك سلحفاة. الخطاء اس تفد من زر Step step و اذلي.2.3.4.5
فكر بايثون 171 6. عدل عىل steer حبيث توجه لك سلحفاة وهجها حنو السلحفاة الاقرب الهيا. تلميح: للسالحف خصةل امسها world و يه مرجع ل TurtleWorld اذلي تعيش فيه و ل TurtleWorld خصةل امسها animals و يه قامئة بلك السالحف يف ذكل الكون. 7. عدل عىل steer حبيث تلعب السالحف اللمسة.)Tag( كل أن تضيف طرائق ل Tagger و ميكنك ختطي steer و init لكن ل ميكنك التعديل عىل أو ختطي step, wobble أو move. و أيضا يسمح ل steer بتغيري اجتاه السلحفاة لكن ليس موقعها. عدل القوانني و طريقة املطاف. steer لتجويد اللعبة مثال جيب متكني السلحفاة البطيئة من ملس السلحفاة الرسيعة يف اخر احلل:.http://thinkpython.com/code/Tagger.py
فكر بايثون 172 الفصل التاسع عرش دراسة حاةل: تيكنرت Tkinter 19.1 واهجة املس تخدم الرسومية GUI معظم الربامج اليت رأينا حلد الان نصية الطابع. لكن الكثري من الربامج تس تخدم و اهجات مس تخدم رسومية و تسمى أيضا.GUI يوفر لنا ابيثون عدة خيارات لكتابة برامج GUI من مضهنا wxpython و Tkinter و.QT للك مهنا حسناته و نقاط ضعفه و لهذا السبب مل يس تقر ابيثون عىل أحدها ليكون اخليار المنوذيج. اخليار اذلي سأقدمه هنا هو Tkinter لنين أعتقد بأنه السهل للمبتدئ. لك املفاهمي يف هذا الفصل تنطبق عىل مديولت ال GUI الاخرى. هناكل الكثري من الكتب و صفحات الويب تتعلق بتكنرت أحد أفضلها هو "مقدمة لتكنرت" لفردريك لنض. لقد كتبت مديول امسه الفصل مبنية عىل هذا املديول. Gui.py هنا مثال بس يط خيلق و يظهر واهجة مس تخدم رسومية: لجياد واهجة مس تخدم رسومية عليك اس ترياد Gui من سوميب: أو قد يبدو كهذا )حسب كيف نصبت سوميب(: مث عليك معل جتلية من اكئن :Gui يأيت مع سوميب. يوفر واهجة مبسطة اىل الاقرتاانت و الفئات يف تكنرت و الامثةل يف هذا from swampy.gui import * from Gui import * g = Gui() g.title('gui') g.mainloop() عندما تشغل هذا النص سرتى انفذة رمادية بعنوان.Gui تشغل حلقة mainloop حلقة انتظار احلدث) event )loop و اليت تنتظر من املس تخدم القيام بيشء ما لرتد عليه. و يه حلقة ل منهتية تظل تعمل اىل أن يغلق املس تخدم النافذة أو يضغط Control C أو يفعل شيئا جيعل الربانمج يتوقف. ل تقوم هذه الواهجة بأي يشء لهنا ل متكل أية وشائط.Widgets الوشائط يه العنارص اليت تكون واهجة املس تخدم الرسومية و من مضهنا: الزر :Button وش يطة حتتوي عىل كتابة أو صورة و تقوم بعمل ما عندما تضغط.
فكر بايثون 173 القامشة :Canvas مساحة تعرض خطوطا أو مربعات أو دوائر أو أي شلك اخر. املدخةل :Entry مساحة حيث يطبع املس تخدم الكتاابت. رشيط مترير :Scrollbar وش يطة حتدد اجلزء املريئ من وش يطة أخرى. اطار :Frame حاوية يف الغالب مرئية حتتوي عىل وشائط أخرى. املس تطيل الرمادي اذلي رأيته عندما أوجدت واهجة املس تخدم اكن اطارا. و لكام أنشأت وش يطة س تضاف اىل هذا الطار. 19.2 توجد الطريقة الازرار و معاودات النداء Buttons and callbacks وش يطة زر: bu button = g.bu(text='press me') القمية املرجتعة من bu يه اكئن.Button و الزر اذلي يظهر يف الاطار هو متثيل رسويم لهذا الاكئن و ميكنك التحمك ابلزر عن طريق اس تدعاء طرائق عليه. تأخذ bu حوايل 32 برمرت للتحمك مبظهر و وظائف الزر. و هذه الربمرتات تسمى هنا خيارات.options و بدل من تزويد القمي للك ال 32 خيارا. بوسعك اس تخدام قرائن لكامت مفاتيح مثل me' text = 'Press لتحديد اخليارات اليت تريد و ترتك البايق للقمي الافرتاضية. عند اضافتك وش يطة اىل الاطار فانه يتقلص لها "."shrink-wrapped أي أن الاطار يتقلص اىل جحم الزر. و ان أضفت وشائط اخرى س يكرب جحم الاطار مبقدار يكفي لستضافهتا. la الطريقة توجد وش يطة ملصق : Label label = g.la(text='press the button') ابلوضع الويل يكدس تكنرت الوشائط من الاعىل اىل الاسفل و يوسطها. سرنى قريبا كيف نتخطى هذا السلوك. ان ضغطت الزر فسرتى بأنه ل يقوم ابلكثري. و ذكل لنك "مل توصل أسالكه بعد" أي مل تقل هل ما يفعل. اخليار اذلي يتحمك ابلزر هو ملصقا جديدا: الان ميكننا انشاء زر هل هذا اخليار:.command و قمية command هو اقرتان سيمت تنفيذه عندما ي ضغط الزر. هنا مثال ينشئ def make_label(): g.la(text='thank you') button2 = g.bu(text='no, press me!', command=make_label) فعندما تضغط هذا الزر عليه أن ينفذ اقرتان make_label و جيب أن يظهر ملصقا جديدا. قمية اخليار command يه اكئن اقرتان و هو ما يعرف"مبعاود النداء : "callback لنك عندما تنادي bu لنشاء الزر فان رساين التنفيذ س يعاود النداء عندما يضغط املس تخدم الزر. هذا النوع من الرساين هو من صفات الربجمة املقادة ابلحداث.event-driven programming أفعال املس تخدم مثل ضغط زر و الرضابت عىل لوحة املفاتيح تسمى أحدااث يف الربجمة املقادة ابلحداث يعمتد رساين الربانمج عىل أفعال املس تخدم أكرث من املربمج. التحدي يف اسلوب الربجمة هذا هو بناء مجموعة من الوشائط و بردود نداء تعمل بشلك حصيح )أو تصدر رساةل خطأ واحضة
احلل: فكر بايثون 174 و مناس بة( لي تسلسل من الافعال اليت يقم هبا املس تخدم. مترين 19.1 اكتب برانجما ينشئ واهجة مس تخدم هبا زر. عند ضغطه عليه أن ينشئ زرا اخر. و عند ضغط الاخر ينشئ ملصقا يقول job!"."nice ما اذلي س يحدث ان ضغط الزر أكرث من مرة http://thinkpython.com/code/button_demo.py 19.3 وشائط مقاشة الرمس مقاشة الرمس يه من أكرث الوشائط تنوعا و يه تنشئ مساحة لرمس اخلطوط و ادلوائر و الاشاكل الاخرى. ان حللت المترين 15.4 فأنت عىل دراية بقامشة الرمس. ca الطريقة تنشئ Canvas جديدة: canvas = g.ca(width=500, height=500).height و width يه أبعاد مقاشة الرمس ابلبكسل. ل يزال بوسعك بعد انشاء الوش يطة تغيري قمي اخليارات ابلطريقة.config مثال خيار bg سغري لون اخللفية: Canvas.config(bg='white') قمية bg يه حمارف ابمس اللون. مجموعة الالوان املتاحة ختتلف ابختالف تطبيقات ابيثون لكن لك التطبيقات توفر عىل الاقل: الاشاكل املرسومة عىل مقاشة الرمس تسمى عنارص للغرابة دائرة: white black red green blue cyan yellow magenta circle مفثال طريقة items املسامة Canvas ترمس item = canvas.circle([0,0], 100, fill='red') القرينة الاوىل يه زوجني من الاحداثيات حتدد مركز ادلائرة و الثانية يه نصف القطر. يوفر Gui.py نظام املس توى ادلياكريت المنوذيج. فيه نقطة الاصل يه وسط مقاشة الرمس و انلور الصادي املوجب يتجه اىل الاعىل. و هو عىل خالف الانظمة الاخرى حيث نقطة الاصل تكون يف الزاوية اليرسى العليا و انلور الصادي املوجب يتجه اىل الاسفل. اخليار fill يعين أن ادلائرة سمتل ابللون الامحر. و القمية املرجتعة من circle يه اكئن عنرص يوفر طرائق للتعديل عىل العنرص عىل القامشة. مثال ميكنك اس تخدام config لتغيري أي من خيارات ادلائرة: مسك خط حميط ادلائرة هو مترين item.config(fill='yellow', outline='orange', width=10) width و الوحدة يه بكسل و لونه هو outline 19.2 اكتب برانجما ينشئ مقاشة و زر. عندما يضغط املس تخدم الزر جيب أن يرمس دائرة عىل القامشة.
19.4 تسلسالت الاحداثيات فكر بايثون 175 طريقة rectangle تأخذ تسلسال من الاحداثيات لتحدد الزوايتني املتقابلتني يف املس تطيل. يرمس املثال التايل مس تطيل ركنه السفىل الايرس يف نقطة الاصل و الركنن املقابل يف النقطة )200,100( : canvas.rectangle([[0, 0], [200, 100]], fill='blue', outline='orange', width=10) تسمى هذا الطريقة (حتديد الركنني) ابلصندوق انليط bounding box لن النقطتني حت وطان املس تطيل. تأخذ ovel صندوقا حميطا و ترمس بيضاواي مضن حدود املس تطيل: و تأخذ و canvas.oval([[0, 0], [200, 100]], outline='orange', width=10) line تسلسال من الاحداثيات لرتمس خطا يصل بني النقاط يرمس املثال التايل ضلعي مثلث: canvas.line([[0, 100], [100, 200], [200, 100]], width=10) polygon تأخذ نفس القرائن ال أهنا ختط اخر ضلع يف املضلع )ان تتطلب الامر( و متله: Canvas.polygon([[0, 100], [100, 200], [200, 100]], fill='red', outline='orange', width=10) 19.5 تنشئ املزيد من الوشائط يوفر تكنرت وش يطتني تسمحان للمس تخدم بطباعة النصوص: املدخةل Entry و يه لسطر واحد و وش يطة Text و يه للسطور املتعددة. en مدخةل جديدة: خيار text يسمح كل ابدخال النص يف املدخةل عند انشاهئا أما طريقة غريه املس تخدم(: تنشئ ننشئ entry = g.en(text='default text') get فرتجع حمتوى املدخةل )و اذلي قد يكون >>> entry.get() 'Default text' te وش يطة :Text text = g.te(width=100, height=5) هنا width و height تضع insert نصا يف وش يطة : Text هام أبعاد الوش يطة ابحلروف و السطور. text.insert(end, 'A line of text') و END يه مؤرش خمصوص يؤرش اىل أخر حرف يف وش يطة. Text ميكنك حتديد حرف ابس تخدام املؤرش املنقوط مثل 1.1 يكون رمق السطر قبل النقطة و رمق العمود بعدها. يف املثال التايل تضاف احلروف nother اىل ما بعد احلرف الاول يف السطر الاول: تقرأ طريقة >>> text.insert(1.1, 'nother') get النص من الوش يطة و تأخذ مؤرشي البداية والهناية كقرائن. يف املثال التايل ي رجع لك النص من الوش يطة و من مضنه حرف السطر اجلديد: >>> text.get(0.0, END) 'Another line of text\n'
فكر بايثون 176 حتذف طريقة delete النص من الوش يطة. هذا املثال حيذف لك احلروف ما عدا الاول و الثاين: >>> text.delete(1.2, END) >>> text.get(0.0, END) 'An\n' مترين 19.3 عدل حكل للمترين 19.2 ابضافة مدخةل و زر اثن. عندما يضغط املس تخدم الزر الثاين جيب أن يقرأ امس اللون من املدخةل. و يس تخدمه لتغيري لون ادلائرة. اس تخدم config لتعديل ادلائرة املوجودة ل تنشئ دائرة جديدة. عىل برانجمك أن يكون قادرا عىل التعامل مع احلالت اليت حياول فهيا املس تخدم تعديل لون دائرة مل تنشأ و مع احلالت اليت يكون فهيا اللون غري صاحل. 19.6 تغليف الوشائط حىت الان ل زلنا نكدس الوشائط يف معود واحد لكن يف معظم واهجات املس تخدم الرسومية يكون النسق معقدا أكرث من هذا. مثال الشلك 19.1 يظهر نسخة بس يطة من عامل السلحفاة )أنظر الفصل 4( يقدم كل هذا القسم النص اذلي ينشئ هذه الواهجة و هو مقسم اىل سلسةل من اخلطوات. ميكنك حتميل املثال اكمال من.http://thinkpython.com/code/SimpleTurtleWorld.py يف أعىل مس توى فهيا حتتوي هذه الواهجة عىل وش يطتني مقاشة و اطار مرتبتان يف صف واحد. اذن فاخلطوة الاوىل يه انشاء صف. class SimpleTurtleWorld(TurtleWorld): """This class is identical to TurtleWorld, but the code that lays out the GUI is simplified for explanatory purposes""" def setup(self): self.row()... الاقرتان اذلي ينشئ و يرتب الوشائط هو.setup معلية ترتيب الوشائط يف واهجة املس تخدم تسمى تغليف.packing تنشئ row اطار صف و جتعهل "الاطار احلايل". و اىل أن يغلق هذا الاطار أو يفتح اطار جديدا فلك الوشائط س تكدس يف صف. و هنا النص اذلي ينشئ القامشة و اطار العمود اذلي س يحتوي الوشائط الاخرى:
فكر بايثون 177 الشلك 191: عامل السلحفاة بعد تشغيل نص ندفات الثلج self.canvas = self.ca(width=400, height=400, bg='white') self.col() الوش يطة الاوىل يف العمود يه اطار شبيك و حتتوي عىل أربعة أزرار مرتبة اثنان و اثنان: self.gr(cols=2) self.bu(text='print canvas', command=self.canvas.dump) self.bu(text='quit', command=self.quit) self.bu(text='make Turtle', command=sel.fmake_turtle) self.bu(text='clear', command=self.clear) self.endgr() تنشئ gr الش بكة و قرينهتا يه عدد الامعدة. ترت ب الوشائط فهيا من اليسار اىل الميني و من الاعىل اىل الاسفل. يس تخدم الزر الاول self.canvas.dump ملعاودة النداء و الزر الثاين لالنهتاء. و هذه الطرائق حميطة pound methods مما يعين أهنا مرتبطة باكئن حمدد. و عند اس تدعاهئا ت س تدعى عىل الاكئن. الوش يطة التالية يف العمود يه اطار صف حيتوي عىل زر و مدخةل: self.row([0,1], pady=30) self.bu(text='run file', command=self.run_file) self.en_file = self.en(text='snowflake.py', width=5) self.endrow() ]0,1[ القرينة الاوىل ل row يه قامئة حتدد كيف تنظ م املساحات الزائدة بني الوشائط. القامئة تعين أن لك املساحة الزائدة تعطى للوش يطة الثانية و يه املدخةل. ان شغلت هذا النص و عدلت جحم النافذة سرتى بأن جحم املدخةل سيتغري أما جحم الزر فال. اخليار الاسفل. pady جيعل هذا الصف يتكئ عىل حموره الصادي مضيفا هل 30 بكسل من املساحة من الاعىل و مثلها من
endrow حتتفظ تهنيي هذا الصف من الوشائط فالوشائط التالية ستتغلف يف اطار العمود Gui.py بتكديس من الاطارات: عندما تس تخدم col row gr أو تقرأ الطريقة عندما تس تخدم يصبح الاطار احلايل. endrow, endcol أو فكر بايثون 178 لنشاء اطار فانه يذهب اىل اعىل التكديس و يصبح الاطار احلايل. endgr read_file run_code.self.inter أخر وش يطتني اكنتا وش يطة نص و وش يطة زر. لنشاء اطار فس يربز خارج التكديس و الاطار السابق حمتوايت املدخةل تس تخدهما اكمس ملف و تقرأ حمتوايته مث متررها اىل اذلي هو اكئن مف رس يعرف كيف يأخذ انلارف و ينفذها كهنا نص برجمي من ابيثون. def run_file(self): filename = self.en_file.get() fp = open(filename) source = fp.read() self.inter.run_code(source, filename) self.te_code = self.te(width=25, height=10) self.te_code.insert(end, 'world.clear()\n') self.te_code.insert(end, 'bob = Turtle(world)\n') self.bu(text='run code', command=self.run_text) run_text تشبه run_file عدا أهنا تأخذ النص من وش يطة نص بدل من ملف: def run_text(self): source = self.te_code.get(10, END) self.inter.run_code(source, '<user-provided code>') تفاصيل تنسيق الوشائط ختتلف - للسف ابختالف لغات الربجمة و حىت ابختالف مديولت ابيثون. تكنرت لوحده دليه ثالثة اليات لرتتيب الوشائط تسمى هذه الاليات همندسات املساحة.geometry manager و اليت سأعرضها هنا يه grid الاخريني تسميان pack و. place حلسن احلظ تنطبق معظم املفاهمي يف هذا الفصل عىل املديولت الاخرى لواهجات املس تخدم الرسومية و عىل اللغات الاخرى أيضا. 19.7 قوامئ الاختيار و املس تدعوات أزرار قوامئ الاختيار يه وشائط تش به الازرار العادية و عند الضغط علهيا تربز قامئة. و عندما ختتار الفأرة عنرصا مهنا ختتفي هذه القامئة. التايل هو نص برجمي ينشئ زر قامئة تنشئ )ميكنك حتميهل من: n)http://thinkpython.com/code/menubutton_demo.py g = Gui() g.la('select a color:') colors = ['red', 'green', 'blue'] mb = g.mb(text=colors[0]) زر قامئة. mb مبدئيا يكون النص عىل الزر هو امس اللون الافرتاي. احللقة التالية تنشئ عنرص قامئة اختيار واحد
للك لون: فكر بايثون 179 for color in colors: g.mi(mb, text=color, command=callable(set_color, color)) القرينة الاوىل ل mi يه زر القامئة اذلي ترتبط به هذه العنارص. اخليار command هو اكئن ي س تدعى )callable( و هو شي جديد. ما رأيناه اىل الان هو اس تخدام طرائق مرتبطة و اقرتاانت ملعاودة النداء. و يه تعمل جيدا طاملا أنك ل مترر أية قرائن اىل الاقرتاانت. أما ان مل يكن هذا هو احلال فعليك بناء اكئن ي س تدعى و حيتوي عىل اقرتان مثل set_color و قرائنه مثل.color الاكئنات اليت تس تدعى ختزن مرجعا اىل الاقرتان و القرائن كخصال. مث عندما يضغط املس تخدم عىل زر القامئة يقوم معاود النداء بنداء الاقرتان و ميرر هل القرائن اليت خزهنا. هكذا ما ميكن أن يبدو عليه :set_color فعندما خيتار املس تخدم عنرص قامئة اختيارات و ينادى عىل حديثا و يطبع كذكل اللون ان جربت هذا املثال فس ميكنك التأكد من أن )و مل ينادى عندما أنشأت اكئنا ي س تدعى(. def set_color(color): mb.config(text=color) print color set_color فانه يعد زر القامئة لظهار اللون اهلتار set_color نودي عندما اختري عنرص ما الربط 19.8 Binding الربط هو املشاركة بني وش يطة و حدث و معاود نداء: عند حدوث احلدث عىل وش يطة )اكلضغط عىل زر( يمت اس تدعاء معاود النداء. لكثري من الوشائط رابط ابتدايئ. مثال عندما تضغط عىل زر فان هذا الرابط البتدايئ يغري مظهر الزر ليبدو كنه ضغط. و عندما تريخ الضغط فالرابط الابتدايئ يسرتجع املظهر الاصيل للزر مث يس تدعي معاود النداء املرتبط خبيار command لهذا الزر. ميكنك اس تخدام طريقة bind لتخطي الروابط الاصلية و اضافة روابط جديدةعىل سبيل املثال ينشئ املثال التايل رابطا لقامشة )ميكنك حتميل النص يف هذا القسم من.)http://thinkpython.com/code/draggable_demo.py Ca.bind('<ButtonPress-1>', make_circle) القرينة الاوىل يه حدث حمارف اطلق هذا احلدث عندما ضغط املس تخدم زر الفأرة الايرس أحداث الفأرة الاخرى تتضمن ButtonMotion و ButtonRelease و.Double-Button القرينة الثانية مداوةل للحدث. مداول احلدث event handler هو اقرتان أو طريقة ربط مثل معاود النداء لكن الفرق املهم بيهنام هو أن مداول احلدث يأخذ اكئن Event كربمرت. هاك مثال: def make_circle(event): pos = ca.canvas_coords([event.x, event.y]) item = ca.circle(pos, 5, fill='red') حيتوي اكئن احلدث عىل معلومات عن نوع احلدث و تفاصيل أخرى مثل احداثيات مؤرش الفأرة. يف مثالنا هذا املعلومات
فكر بايثون 180 اليت حنتاج الهيا يه املوقع اذلي ضغط عىل زر الفأرة فيه و هذه القمي يه احداثيات ابلبكسل و حي ددها النظام الرسويم اذلي يقبع خلفها. ت رتجم الطريقة canvas_coords هذه القمي اىل احداثيات عىل مقاشة الرمس و يه متوافقة مع طرائق Canvas مثل.circle من الشائع ربط احلدث.Enter املثال التايل يوجد زرا و مدخةل: حيصل >Return< بوشائط املدخالت. و هذا احلدث ي طلق عند الضغط عىل مفتاح Return أو bu = g.bu('make text item:', make_text) en = g.en() enbind('<return>', make_text) Enter ينادى عىل make_text عندما ي ضغط عىل الزر أو عندما يضغط املس تخدم عىل مفتاح بيامن يكتب يف املدخةل. ليك حنقق هذا حنتاج اىل اقرتان ميكن ندا ؤه كمر )بدون قرائن( أو مكداول أحداث )مع حدث كقرينة(: def make_text(event=none): text = en.get() item = ca.text([0,0], text) make_text عىل حمتوايت املدخةل و يعرضها كعنرص Text يف القامشة. ميكن أيضا انشاء رب اط لعنارص القامشة. التايل هو تعريف فئة ل القدرة عىل اجلر و اللقاء.drag-and-drop Draggable و هو فئة ابناء من حتقق لنا Item class Draggable(Item): def init (self, item): self.canvas = item.canvas self.tag = item.tag self.bind('<button-3>', self.select) self.bind('<b3-motion>', self.drag) self.bind('<release-3>', self.drop) تأخذ طريقة init عنرصا كربمرت. و تنسخ خصاهل مث تنشئ روابط لثالثة أحداث: ضغط الزر حركة الزر و ارخاء الزر. مداول احلدث select خيزن احداثيات احلدث احلايل و لون العنرص الصيل مث يغري اللون اىل الاصفر: def select(self, event): self.dragx = event.x self.dragy = event.y self.fill = self.cget('fill') self.config(fill='yellow') "get configuration يه اختصار "هات العدادات cget اخليار. drag حيسب تأخذ امس اخليار مكحارف و ترجع القمية احلالية ذلكل املسافة اليت حتركها الاكئن ابلنس بة لنقطة البداية و حيد ث الحداثيات اهلزنة مث حيرك العنرص. الحداثيات يف هذه احلوسبة يه ابلبكسل و ل حاجة لتحويلها اىل احداثيات القامشة. و يف الهناية تسرتجع drop لون العنرص الصيل: def drag(self, event): dx = event.x - self.dragx dy = event.y - self.dragy self.dragx = event.x self.dragy = event.y self.move(dx, dy)
فكر بايثون 181 ميكنك اس تخدام فئة def drop(self, event): self.config(fill=self.fill) make_circle Draggable لزتويد عنرص موجود ابلقدرة عىل اجلر و اللقاء. مفثال هذه نسخة معدةل من تس تخدم circle لنشاء عنرص و Draggable جلعهل قابال للجر و اللقاء: def make_circle(event): pos = ca.canvas_coords([event.x, event.y]) item = ca.circle(pos, 5, fill='red') item = Draggable(item) هذا مثال لحدى فوائد التوريث: ميكنك تعديل اماكنيات فئة الابء بدون تعديل تعريفها. و هو مفيد خصوصا ان كنت س تغري سلوك مديول معر ف مل تكتبه. 19.9 مثال الخطاء عالج من التحدايت اليت تواهجك يف برجمة GUI يه مالحقة ما حيدث خالل بناء واهجة املس تخدم و ما حيدث كرد عىل أحداث املس تخدم. من الخطاء الشائعة عندما تقوم ابعداد معاود نداء هو نداء الاقرتان بدل من مترير مرجع هل: def the_callback(): print 'Called.' g.bu(text='this is wrong!', command=the_callback()) ان شغلت هذا النص سرتى بأنه ينادي معاود النداء أول مث ينشئ الزر. و عندما تضغط عىل الزر فلن يفعل شيئا لن القمية املرجتعة من the_callback يه. None و يف العادة عليك أل تس تدعي معاود التصال بيامن أنت تعد واهجة املس تخدم مفعاود النداء ي س تدعى فقط كرد عىل حدث من املس تخدم. حتد اخر يف برجمة واهجات املس تخدم الرسومية هو أنك ل تتحمك يف رساين التنفيذ. اهنا أفعال املس تخدم اليت حتدد أي أجزاء الربانمج ستنفذ و ما هو ترتيب هذا التنفيذ. و هذا يعين أن عليك تصممي برانجمك ليعمل بشلك حصيح عند أي تسلسل حممتل للحداث. مثال واهجة املس تخدم الرسومية يف المترين 19.3 لها وش يطتان: واحدة تنشئ عنرص ادلائرة و الاخرى تغري لون ادلائرة. ان أنشأ املس تخدم ادلائرة مث غري لوهنا فال ضري. لكن ماذا لو غري املس تخدم لون دائرة مل توجد بعد أو أنه أنشأ أكرث من دائرة لكام كرب عدد الوشائط أصبح ختيل لك احامتلت تسلسل الاحداث أصعب. احدى طرق التعامل مع هذا التعقيد هو كبسةل حاةل النظام يف اكئن مث الخذ ابلعتبار: ما يه احلالت انلمتةل يف مثال ادلائرة ميكننا اعتبار حالتني: قبل و بعد انشاء املس تخدم دلائرة. يف لك حاةل ما يه الحداث املمكن حدوهثا يف املثال قد يضغط املس تخدم عىل أي من الزرين أو قد ينهتيي. للك زويج حاةل-حدث ما يه اهلرجات املرغوبة مبا أن هناك حالتني و زرين فان هناكل أربعة أزواج حاةل- حدث للخذ ابلعتبار. ما اذلي قد يسبب الانتقال من حاةل اىل اخرى يف حالتنا هذه هناك انتقال عندما ينشئ املس تخدم ادلائرة الاوىل. قد جتد تعريف و اختبار الالمتغريات مفيد فهيي جيب أن تامتسك يف أي تسلسل للحداث.
فكر بايثون 182 هذه املقاربة يف برجمة و-م-ر س تعينك عىل كتابة نص حصيح من دون اضاعة الوقت يف اختبار لك تسسل حممتل لحداث املس تخدم! 19.10 و-م-ر املعاين.graphical user interface واهجة املس تخدم الرسومية :GUI وش يطة :widget احدى العنارص اليت تكون و-م-ر و من مضهنا الزرار و قوامئ الاختيار و حقول ادخال النصوص اخل. خيار :option قمية تتحمك مبظهر و وظيفة الوش يطة. قرينة لكمة مفتاحية :keyword argument قرينة حتدد امس الربمرت كجزء من نداء الاقرتان. معاود النداء :callback اقرتان مرتبط بوش يطة ي نادى عندما يقوم املس تخدم بفعل ما. طريقة مرتبطة :bound method طريقة ترتبط بتجلية حمددة. الربجمة املساقة ابلحداث :event-driven programming اسلوب يف الربجمة تسلسل التنفيذ فيه حتدده أفعال املس تخدم. حدث :event فعل من املس تخدم اكلنقر عىل الفأرة أو الضغط عىل لوحة املفاتيح يسبب ردا من و-م-ر. حلقة انتظار احلدث :event loop حلقة ل منهتية تنتظر فعال من املس تخدم مث ترد. عنرص :item عنرص رسويم عىل وش يطة مقاشة. صندوق الاحاطة :bounding box مس تطيل حييط مبجموعة من العنارص حيدد عادة بركنني متقابلني. تغليف :pack ترتيب و عرض عنارص ال و-م-ر. همندسة املساحة :geometry manager ارتباط بني وش يطة و حدث و مداول احلدث. ينادى مداول احلدث عند حدوث احلدث يف الوش يطة. 19.11 مترين متارين 19.4 يف هذا المترين س تكتب عارضا للصور هذا مثال بس يط: g = Gui() canvas = g.ca(width=300) photo = PhotoImage(file='danger.gif') canvas.image([0,0], image=photo) g.mainloop() Canvas.image PhotoImage الصورة ميكن لتكنرت عرضه. يضع يقرأ PhotoImage ملفا و يرجع اكئن عىل القامشة مركز الصورة هو الاحداثيات املعطاة. ميكنك وضع الصورة عىل امللصقات و الزرار و الوشائط الاخرى: g.la(image=photo) g.bu(image=photo) ميكن ل PhotoImage التعامل مع بعض ملفات الصور مثل GIF, PPM لكن ميكننا اس تخدام مكتبة ابيثون للصور )PIL( Python Image Library لقراءة امللفات الاخرى.
فكر بايثون 183 امس مديول PIL هو image و تكنرت به اكئنا بنفس الامس فنتجنا للرصاع سنست ورد املديول مع يس تورد السطر الاول Image و مينحه الامس انليل.PIL السطر الثاين يس تورد صور PIL اىل صور.Tkinter PhotoImage هذا مثال: :import as import Image as PIL import ImageTk ImageTk اذلي بوسعه ترمجة image = PIL.open('allen.png') photo2 = ImageTk.PhotoImage(image) g.la(image=photo2) -1-2 -3-4 محل image_demo.py و danger.py من http://thinkpython.com/code مث شغل. image_demo.py قد حتتاج اىل تنصيب PIL و.ImageTK قد تكون من مضن براجمك اهلزنة ان مل تكن حفملها من.http://pythonware.com/products/pil يف image_demo.py غري امس الصورة الثانية من photo2 اىل photo مث شغل الربانمج مرة أخرى. جيب أن ترى الصورة الثانية و ليس الاوىل. املشلكة يه أنك عندما تعيد تعيني photo فاهنا ستتخطى املرجع اىل PhotoImage و اليت س تختفي. نفس املشلكة س تحدث ان عينت PhotoImage اىل متغري حميل فس تختفي عند انهتاء الاقرتان. لتجنب هذه املشلكة عليك ختزين مرجعا للك PhotoImage تريد الاحتفاظ هبا. ميكنك اس تخدام متغري معويم أو ختزين الصور يف هيلك بياانت أو كخصةل لاكئن. سلوك كهذا قد يصبح حمبطا و لهذا السبب حذرتك )و لهذا السبب أيضا الصورة العينة تقول )"Danger!" انطالقا من هذا الربانمج اكتب يأخذ امس املدل و يدور يف حلقة ملفاته عارضا أي ملف يتعرف عليه PIL كصورة. ميكنك اس تخدام عبارة try للتقاط امللفات اليت ل يتعرف علهيا.PIL عندما ينقر املس تخدم عىل صورة فعىل الربانمج اظهار الصورة التالية. يوفر PIL تشكيةل من الطرائق للتعامل مع الصور. ميكنك القراءة عهنا عىل:. http://pythonware.com/library/pil/handbook كتحد اخرت بضعة من تكل الطرائق و امعل و-م-ر لتطبيق الطرائق عىل الصور.. احلل: http://thinkpython.com/code/imagebrowser.py مترين 19.5 حمرر الرسوم املتجهة هو برانمج يسمح للمس تخدم برمس و حترير الاشاكل عىل الشاشة و انتاج ملفات الرسوم املتجهة مثل Postscript و.SVG اكتب حمررا بس يطا للرسوم املتجهية ابس تخدام تكنرت. يسمح عىل الاقل برمس اخلطوط و ادلوائر و املس تطيالت و جيب أن يس تخدم Canvas.dump لتوليد توصيف Postscript نلتوى القامشة. و كتحد بوسعك أن متكن املس تخدم من اختيار و تغيري جحم العنارص من القامشة. مترين 19.6 اس تخدم تكنرت لكتابة متصفح ويب بس يط. جيب أن يكون به وش يطة ادخال نصوص حيث يطبع املس تخدم املوقع و تعرض القامشة حمتوايت الصفحة. ميكنك اس تخدام مديول تعريف THML )أنظر: urllib لتحميل امللفات )انظر المترين 14.6( و مديول HTMLParser لترصيف بطاقات. https://docs.python.org/2/library/htmlparser.html عىل متصفحك التعامل مع النصوص البحتة و الارتباطات التشعبية. و كتحد التعامل مع ألوان اخللفية و صياغة شلك نصوص البطاقات و الصور.
فكر بايثون 184
فكر بايثون 185 أ امللحق عالج الاخطاء قد حتدث أشاكل خمتلفة من الخطاء يف الربانمج. و من املهم التفريق بيهنا لصيدها برسعة: حتدث أخطاء النحو يف ابيثون عندما يرتمج النص املصدر اىل نص البت. و يه يف العادة تعين بأن هناك خطأ يف حنو الربانمج. مثال: نسيان الفاصةل يف هناية عبارة def يصدر رساةل اخلطأ )الزائدة( SyntaxError:. invalid syntax أخطاء عند التشغيل يظهرها املف رس عندما حيدث خطأ بيامن يعمل الربانمج. معظم رسائل هذه الخطاءتقول أين وقع اخلطأ و أي اقرتان اكن ينفذ عندها. مثال: الاجرتار الال منهتيي يسبب يف الاخر خطأ عند التشغيل "العمق الاقىص لالجرتارات مت تعديه "maximum recursion depth exceeded الخطاءادلللية يه مشالك الربامج اليت تعمل و مل تصدر رسائل خطأ لكهنا ل تقوم ابلعمل املطلوب. مثال: تعبري مل يقمي ابلشلك اذلي تريده ينتج نتيجة غري حصيحة. اخلطوة الاوىل يف عالج الخطاء يه أن تعرف أي نوع من الخطاء تواجه. رمغ كون الاقسام التالية مرتبة حسب نوع اخلطأ ال أن بعضها يطبق يف عدد من الظروف. النحوية الخطاء أ- 1 يسه ل اصالح هذه الخطاء يف العادة عندما تعرف ما هو اخلطأ. و للسف فرسائل اخلطأ ليست واحضة دامئا. أكرث الرسائل ش يوعا يه SyntaxError: invalid syntax و SyntaxError: invalid.token و ليس أي مهنام تفيدان مبعلومات اكفية. لكن عىل اجلانب الاخر فالرساةل ختربك أين وقعت املشلكة. احلقيقة أهنا ختربك أي لحظ ابيثون املشلكة و هو ليس ابلرضورة ماكن اخلطأ. أحياان يكون اخلطأ سابقا ملاكن الرساةل و يف الغالب السطر السابق. ان كنت قد بنيت الربانمج ابلتدرجي فيجب أن يكون دليك فكرة عن ماكن وجود اخلطأ س يكون يف أخر سطر كتبته. ان كنت قد نسخت النص من كتاب ابدأ مبقارنة النصني بعناية احفص لك حرف. يف نفس الوقت تذكر بأن اخلطأ قد يكون يف الكتاب فان رأيت فيه ما يظهر كنه خطأ حنوي فقد يكون خطأ حنوي فعال. هنا بعض الطرق اليت جتنبك -1 الخطاءالنحوية: تأكد من أنك ل تس تعمل لكامت ابيثون املفتاحية مكتغريات.
2- تأكد من وجود نقطتان يف هناية ترويسة العبارات املركبة مثل فكر بايثون 186.for, while, if, def 3- تأكد من وجود عالمات الاقتباس قبل و بعد انلارف. -4-5 -6-7 ان اكن دليك حمارفا متعددة السطور مع عالمات الاقتباس الثالثة )مفردة أو مزدوجة( تأكد من أنك أغلقت انلارف ابلشلك الصحيح. انلارف غري املقفةل تسبب invalid token يف هناية برانجمك أو أهنا س تعامل الاجزاء الالحقة يف الربانمج مكحارف اىل أن تصل اىل انلارف التالية. و يف احلاةل الثاين قد ل تصدر رساةل خطأ عىل الاطالق!! الاقواس الغري مقفةل {,),] تتسبب يف جعل ابيثون يسمتر اىل السطر التايل عىل أنه جزء من العبارة. يف العموم يصدر اخلطأ يف السطر التايل حلظيا تقريبا. انتبه للخطأ التقليدي = بدل من == يف املرشوطات. انتبه للمسافات البادئة و أهنا مصطفة ابلشلك اذلي جيب أن تكون عليه. ابيثون يس تطيع التعامل مع الفراغات و مسافات اجلدوةل لكن ان خلطهتام فستتسبب ابملشالك. أفضل طريقة لتجنب هذه الخطاء يه اس تعامل حمرر نصوص يعمل عن ابيثون و يدرج املسافات البادئة الصحيحة. ان مل ينفع أي من السابق فانتقل اىل القسم التايل... أ- 1-1 أغري و أبدل لكن ل يشء يتغري. ان قال املف رس أن هناك خطأ يف النص لكنك ل ترى أين فقد يعين أنكام )أنت و املف رس( ل تنظران اىل نفس النص. احفص يف بيئة الربجمة دليك ان اكن النص اذلي حترره هو النص اذلي حياول ابيثون تشغيهل. ان مل تكن متأكدا فتعمد وضع خطأ يف بداية النص. الن شغل الربانمج مرة اثنية. ان مل جيد املف رس اخلطأ اجلديد فانه يشغل ملفا اخر. املهتمون انلمتلون هنا قليلون: أنت لقد عدلت عىل النص و مل حتفظ امللف قبل التشغيل. بعض بيئات الربجمة تقوم هبذا عنك لكن بعضها ل. أنت غريت امس امللف لكنك لزلت تشغل امللف ذو الامس القدمي. بيئة الربجمة هناك يشء مل ي ع د ابلشلك الصحيح. ان كنت تكتب مديول انتبه لئال تعطيه اسام موجودا لحد مديولت ابيثون. ان اس توردت ب import لقراءة مديول فتذكر بأن عليك أعادة تشغيل املف رس أو س تخدام ملف معدل. ان اس توردت املديول اثنية فانه ل يفعل أي يشء. لقراءة reload ان علقت و مل تس تطع اكتشاف ما اذلي حيدث فهناك مقاربة أخرى و يه البدء بيشء جديد مثل برانمج " Hello, "World! للتأكد من أنه ابماكنك جعل برانمج معروف يعمل. مث ابدأ ابضافة أجزاء برانجمك ابلتدرجي اىل الربانمج اجلديد.
أ- 2 أخطاء عند التشغيل فكر بايثون 187 عندما يكون برانجمك حصيح حنواي فسيمتكن ابيثون من تشغيهل أو البدء يف تشغيهل. مفا اذلي ميكن أن خيفق الان أ- 1-1 برانجمي يقوم بال يشء البتة. تش يع هذه املشلكة عندما يتكون برانجمك من فئات و اقرتاانت لكنه ل يس تدعي شيئا لبدء التنفيذ. قد تتعمد هذا متعمدا ان كنت ختطط لس ترياد هذا املديول للزتود ابلفئات و الاقرتاانت. ان مل يكن هذا هو املقصود فتأكد أنك تس تدعي اقرتاان لبدء التنفيذ أو نفذ اقرتاان يف الوضع التفاعيل. أيضا نظر قسم "رساين التنفيذ" الالحق. أ- 2-2 برانجمي يعلق ان توقف برانمج و ظهر بأنه ل يقوم بيشء فهو عالق.hanging كثريا ما يعين هذا أنه علق يف حلقة ل منهتية أو اجرتار ل منهتيي. ان اكنت هناك حلقة ما تشك فهيا فأضف عبارة بعد احللقة مبارشة و لتقل "ها أان أخرج من احللقة". print قبلها مبارش و لتقل فهيا "ها أان أدخل احللقة" و عبارة شغل الربانمج و ان رأيت "ها أان أدخل احللقة" و مل تر "ها أان أخرج من احللقة" فأنت يف حلقة غري منهتية ان حدث هذا فانتقل اىل القسم "احللقة الال منهتية". يف معظم الاحيان يتسبب الاجرتار الال منهتيي يف جعل الربانمج يعمل لفرتة مث يصدر رساةل:.RuntimeError: Maximum recursion depth exceeded ان حدث هذا فانتقل اىل القسم "الاجرتار الالمنهتيي" الالحق. ان مل تعمل أي من هاتني الطريقتني فابدأ ابختبار احللقات و الاجرتارات الاخرى و كذكل الطرائق. ان مل حيل هذا املشلكة فقد يعين أنك ل تفهم رساين التنفيذ لربانجمك. اذن فاذهب اىل القسم "رساين التنفيذ" الالحق. حلقة ل منهتية ان كنت تظن أن دليك حلقة ل منهتية و تظن بأنك تعمل أي لتطبع قمي املتغريات يف املرشوطة و قمية املرشوطة. مهنا اليت تسبب املشلكة فأضف عبارة print مكثال: يف هنايهتا while x > 0 and y < 0 : # do something to x # do something to y print "x: ", x print "y: ", y
فكر بايثون 188 print "condition: ", (x > 0 and y < 0) الان عندما تشغل الربانمج سرتى ثالثة سطور من اهلرجات للك لفة يف احللقة. و اخر لفة يف احللقة س يكون الرشط. False أما ان اس مترت احللقة ابلعمل فسرتى قمي x و y و قد تكتشف السبب اذلي جيعلهام ل يتحداثن ابلشلك الصحيح. اجرتار ل منهتيي يف معظم الاحيان يتسبب الاجرتار الال منهتيي يف جعل الربانمج يعمل لفرتة مث يصدر رساةل: RuntimeError:.Maximum recursion depth exceeded ان شككت بأن اقرتاان أو طريقة ما يه ما يسبب الاجرتار الال منهتيي فابدأ البحث للتأكد من وجود حاةل الاساس. بلكامت أخرى: جيب أن يكون هناك رشط ما جيعل الاقرتان أو الطريقة ترجع دون التسبب يف اس تدعاء اجرتاري. ان مل يكن فعليك اعادة التفكري يف اخلوارزمية و أن حتدد حاةل أساس. ان اكنت هناك حاةل أساس لكن الربانمج ل يصل الهيا فأضف عبارة print بداية الاقرتان أو الطريقة و لتطبع الربمرتات. الان عندما تشغل الربانمج سرتى سطورا من اهلرجات يف لك مرة ي س تدعى فهيا الاقرتان أو الطريقة ان اكنت الربمرتات ل تتطور حنو احلاةل الاساس فس يكون دليك فكرة عام حيدث. رساين التنفيذ ان مل تكن متأكدا من كيفية سري التنفيذ يف برانجمك أضف print يف بداية لك اقرتان و لتطبع شيئا ك " entering "function foo حيث foo هو امس الاقرتان. الان عندما تشغل الربانمج س تطبع مالحقة للك اقرتان مت اس تدعاؤه. أ- 3-3 عندما أشغل الربانمج أحصل عىل اس تثناء ان حدث خطأ خالل التشغيل س يطبع ابيثون رساةل حتتوي امس الاس تثناء و السطر اذلي حدثت عنده املشلكة و مالحقة. املالحقة تس مي الاقرتان اذلي اكن ينفذ حيهنا و الاقرتان اذلي اس تدعى هذا الاقرتان و الاقرتان اذلي اس تدعاه و هكذا. بلكامت اخرى فهيي تالحق تسلسل اس تدعاءات الاقرتاانت اليت أوصلت الربانمج اىل هذه احلال. حتتوي املالحقة أيضا عىل رمق السطر اذلي حدث فيه النداء. اخلطوة الاوىل يه حفص ماكن حدوث اخلطأ يف الربانمج و حماوةل التعرف عىل املشلكة هناك. هنا بعض اليت حتدث عند التشغيل: خطأ يف التسمية :NameError أنت حتاول اس تخدام متغري غري موجود يف البيئة. تذكر أن املتغريات انللية يه حملية. فال ميكنك الاشارة الهيا من خارج الاقرتان اذلي عرفت فيه. خطأ يف المنط :TypeError هناكل عدة أس باب حممتةل: الخطاءالشائعة
فكر بايثون 189 أنت حتاول اس تخدام قمية بطريقة خاطئة. مثال: اس تخدام يشء غري الاعداد الصحيحة مكؤرشات يف القوامئ انلارف أو التوبل. هناك عدم تطابق بني العنارص يف حمارف صيغة و العنارص اليت مررت للتحويل. قد حيدث هذا اما لعدم تطابق عدد العنارص أو النداء عىل حتويل غري صاحل. أنت مترر العدد اخلطأ من القرائن لقرتان أو طريقة. للطرائق أنظر يف تعريف الطريقة للتأكد من أن الربمرت الاول هو.self مث انظر اىل اس تدعاء الطريقة للتأكد أن اس تدعاءها اكن عىل اكئن هل المنط الصحيح و يزود القرائن الصحيحة. أخطاء املفاتيح :KeyError أنت حتاول الوصول اىل عنرص يف القاموس ابس تخدام مفتاح ل حيتويه القاموس. أخطاء اخلصال :AttributeError أنت حتاول الوصول اىل خصةل أو طريقة غري موجودة. تأكد من الهتجئة!! ميكنك اس تخدام dir لرسد مجيع اخلصال املوجودة. ان اكن اخلطأ يقول NoneType فهذا يعين أنه ان وصلت اىل هناية الاقرتان دون أن تصادف عبارة النتيجة من طرق القوامئ مثل sort و اليت ترجع.None. أحد الاس باب الشائعة هو نس يان ارجاع القمية من الاقرتان فسوف ترجع, None و سبب شائع اخر هو اس تخدام None return خطأ املؤرش :IndexError املؤرش اذلي تس تخدمه للوصول اىل عنرص يف قامئة أو حمارف أو توبل أكرب من طولها انقص واحد. أضف عبارة print قبل موقع اخلطأ مبارشة و لتطبع قمية املؤرش و طول املصفوفة. هل املصفوفة ابلطول الصحيح هل املؤرش ابلقمية الصحيحة من املدي اس تخدام معاجل أخطاء ابيثون )pdb( لنه يالحق الاس تثناءات و يسمح كل برؤية حاةل الربانمج قبل اخلطأ. ميكنك القراءة عن pdb عىل:. http://docs.python.org/2/library/pdb.html أ- 2-4 أضفت الكثري من عبارات print اىل أن مغرتين اهلرجات من مشالك اس تخدام print يف عالج الخطاء يه أنك تكتشف نفسك مطمورا ابهلرجات. هناك طريقتان لتمكل عالج برانجمك: بسط اهلرجات أو بسط الربانمج. لتبس يط اهلرجات ميكنك حذف عبارات فتصبح أسهل للفهم. print اليت ل تساعد أو التعليق علهيا أو ميكنك جتميعها معا أو تغيري تنس يقها لتبس يط الربانمج هناك العديد من الش ياء اليت ميكنك فعلها. أولها ختفيض جحم املسأةل اليت يعمل علهيا الربانمج. مثال ان اكن يبحث يف قامئة صغر هل جحمها. ان اكن الربانمج يأخذ مدخال من املس تخدم اعطه أبسط مدخل يسبب املشلكة. اثنهيا تنظيف الربانمج. أزل النصوص امليتة و أعد ترتيب الربانمج بشلك يسهل معه فهمه. مثال ان كنت تشك بأن املشلكة موجودة يف جزء عيش من الربانمج حاول اعادة كتابة اجلزء العيش و تبس يط بنائه. ان كنت تشك يف اقرتان خضم حاول جتزئته اىل اقرتاانت أصغر و حفصها متفرقة. يف الغالب تكون معلية العثور عىل حاةل الفحص الصغرى يه ما تدكل عىل البقة. ان لحظت بأن الربانمج يعمل يف مواقف و ل يعمل يف اخرى فاس تخدم هذا كدليل ملا حيدث. و يف نفس الس ياق فاعادة كتابة جزء من النص يساعد يف العثور عىل البقات ادلقيقة. فان مقت بتغيري تعتقد أنه لن يؤثر عىل
فكر بايثون 190 الربانمج ال أنه أثر فهذا تلميح اخر تس تفيد منه. ادلللية الخطاء أ- 3 عالج الخطاء ادلللية أصعب مفي بعض النوايح ذكل لن املف رس ل يزودك مبعلومات عام حيدث. أنت فقط من يعمل ما عىل الربانمج القيام به. اخلطوة الاوىل أن تربط بني نص الربانمج و السلوك اذلي تراه. جيب أن تكون دليك فرضية عام حيدث من الربانمج فعليا. و مما يصعب هذه املهمة يه أن احلواسيب رسيعة. قد ترغب أحياان يف ابطاء الربانمج اىل رسعة برشية. بعض معاجلات الخطاءتفعل ذكل. لكن الوقت املستنفذ يف ادراج بعض عبارات print يكون يف الغالب أقل من ذكل املطلوب لعداد معاجل أخطاء و ادراج و حذف نقاط الفحص و تسيري الربانمج خبطوات اىل ماكن حدوث املشلكة. أ- 1-1 برانجمي ل يعمل. عليك أن تسأل نفسك هذه الاس ئةل: هل هناك يشء مما يفرتض من الربانمج معهل لكنه ل حيدث اعرث عىل الفقرة من النص و اليت ينفذ فهيا ذكل الاقرتان و تأكد من أهنا تنفذ يف عندما جيب أن تنفذ. هل هناك يشء حيدث و يفرتض أل حيدث اعرث عىل الفقرة يف الربانمج اليت تقوم بذكل الاقرتان و تأكد من أهنا تنفذ فقط عندما جيب أن تنفذ. هل هناك فقرة يف الربانمج تقوم بتأثري غري اذلي تتوقعه تأكد من أنك تفهم النص املقصود خصوصا ان اكن به اس تدعاءات اىل اقرتاانت أو طرائق من مديولت ابيثون الاخرى. اقرأ واثئق الاقرتان اذلي تس تدعيه. جربه بكتابة حاةل حفص بس يطة و احفص النتاجئ. ليك تربمج جيب أن يكون دليك منوذج عقيل للطريقة اليت تعمل هبا الربامج. فان كتبت برانجما ل يقوم مبا تريده فاملشلك يف كثري من الاحيان ليست يف الربانمج بل يف المنوذج العقيل اذلي بنيته. أفضل طريقة لتصحيح منوذجك العقيل عن الربانمج يه تقسميه اىل مكوانت )عادة الاقرتاانت و الطرائق( و حفص لك مكون عىل حدة. و مبجرد عثورك عىل التناقض بني المنوذج و الواقع ستمتكن من حل املشلكة. طبعا جيب أن تبين و ختترب بيامن تصمم برانجمك. ان واهجت مشلكة فس يكون جحم ما عليك حفصه من النصوص صغريا و يه يف الغالب الاضافات اجلديدة. أ- 1-2 دلي تعبري مشعراين كبري و ل يقوم مبا أتوقعه منه. ل بأس يف كتابة التعبريات الكبرية طاملا أن قراءهتا سهةل لكهنا تكون صعبة العالج من الاخطاء. التفكري السلمي هو تقسمي التعبريات املعقدة اىل مجموعة من التعيينات اىل متغريات مؤقتة. مثال:
فكر بايثون 191 self.hands[i].addcard(self.hands[self.findneighbor(i)].popcard()) ميكن كتابته هكذا: neighbor = self.findneighbor(i) pickedcard = self.hands[neighbor].popcard() self.hands[i].addcard(pickedcard) النسخة املسهبة اسهل للقراءة لن أسامء املتغريات تضيف اىل املعلومات و يه اسهل للعالج لنك تس تطيع حفص أمناط املتغريات الوس يطة و قميها. مشلكة اخرى للتعبريات الضخمة يه أن تراتب تقيميها قد ل يكون ما تتوقع. مثال ان كنت ترتمج التعبري x/2π اىل ابيثون فقد تكتب: y = x / 2 * math.pi و هذا غري حصيح لن الرضب و القسمة هلام نفس الاس بقية و تقمي من اليسار اىل الميني. اذن فهذا التعبري س يقمي عىل أنه. xπ/2 أفضل طريقة لعالج التعبريات يه اس تخدام الاقواس جلعل ترتيب التقيمي واحضا: y = x / (2 * math.pi) فأيامن كنت غري متأكد من ترتيب التقيمي اس تخدم الاقواس. ليس فقط ليكون الربانمج حصيحا )يقوم مبا تريد( و لكن جلعهل مقروءا لولئك اذلين مل حيفظوا قوانني الاس بقية. return أ- 3-3 دلي اقرتان أو طريقة ل ترجع ما أتوقعه مهنا. ان اكنت دليك عبارة return يف تعبري معقد فلن يكون دليك الوقت لطباعة قمية ميكنك اس تخدام املتغريات املؤقتة. مثال بدل من: ميكنك كتابة: هكذا تكون دليك الفرصة لطباعة قمية count قبل الارجاع. قبل الارجاع. مرة أخرى return self.hands[i].removematches() count = self.hands[i].removematches() return count أ- 3-4 أان يف ورطة حقيقية و أريد املساعدة. أول حاول الابتعاد عن احلاسوب لعدة دقائق. احلواسيب تصدر أمواج تؤثر يف املخ و تسبب هذه العراض: الحباط و الغضب. الميان ابخلرافات "هذا احلاسوب يكرهين" و التفكري السحري )"انه يعمل عندما ارتدي قبعيت ابلعكس"(. برجمة اخلطى العشوائية )حماوةل كتابة لك الربامج انلمتةل و اختيار الربانمج اذلي يقوم ابلعمل الصائب(. ان لحظت أنك تعاين احدى هذه الاعراض قف و اذهب يف مشوار. و عندما هتدأ فكر يف الربانمج. ما اذلي يفعهل ما يه الاسباب انلمتةل لسلوكه هكذا مىت اكن الربانمج يعمل بشلك حصيح و ما اذلي فعلته بعدها
فكر بايثون 192 أحياان العثور عىل البق يس تغرق الوقت. كثريا ما أعرث عىل الخطاء بيامن أان بعيد عن احلاسوب عندما أجعل دماغي يرسح. من أفضل الاماكن للعثور عىل البق يه القطارات ادلش و الرسير قبل النوم. أ- 3-5 ل أان فعال حباجة للمساعدة. هذه أمور حتدث. حىت أفضل املربجمني هل كبوات. أحياان تعمل عىل برانمج لفرتة طويةل مبا فيه الكفاية لتجعكل ل ترى اخلطأ. اس تخدام زويج عيون طازجة هو احلل. قبل أن تطلب املساعدة من أحد تأكد من أنك مس تعد. برانجمك جيب أن يكون بس يطا قدر الماكن و جيب أن تكون مهنماك بفحصه بأبسط مدخل ممكن للتسبب ابخلطأ. جيب أن تكون قد وضعت عبارات print يف الامكنة املناسبة )و ما تطبعه هذه العبارات جيب أن يكون مفهوما(. جيب أن تكون فاهام للمشلكة ابلقدر اذلي يسمح كل برشهحا بوضوح. و عندما تستشري أحدمه تأكد من اعطائه املعلومات اليت س يحتاهجا: ان اكنت هناك رسائل خطأ مفا يه و بأي جزء من الربانمج تتعلق ما هو اخر يشء مقت به قبل وقوع اخلطأ ماذا اكنت أخر السطور اليت كتبهتا قبهل أو ما يه حاةل الاختبار اجلديدة اليت فشلت. ما اذلي جربته حللها حىت الان و ماذا تعلمت منه و عندما جتد البقة فكر لثوان ابذلي اكن جيب فعهل للعثور علهيا أرسع. ففي املرة التالية اليت ترى فهيا شيئا مماثال ستمتكن من الامساك هبا أرسع. تذكر بأن الهدف ليس جعل الربانمج يش تغل. بل التعمل كيف جتعل الربانمج يش تغل.
فكر بايثون 193 امللحق ب حتليل اخلوارزميات هذا امللحق هو اقتباس حم رر من "فك ر تعقيدات" ل ألن ب. داوين من منشورات أورييل ميدا. 2011 عند انهتائك من هذا الكتاب قد تود الانتقال اىل ذاك. حتليل اخلوارزميات هو فرع من علوم احلاسوب يبحث يف أداء اخلوارزميات خصوصا زمن تشغيلها و املساحة املتطلبة لها. أنظر.http://em.wikipedia.org/wiki/Analysis_of_algorithms الهدف العميل من حتليل اخلوارزميات هو توقع أداء اخلوارزميات اهلتلفة لالس تدلل عند اصدار القرارات يف مرحةل التصممي. يف المحةل الرئاسية لعام 2008 عندما زار املرحش ابراك أوابما جوجل ط لب منه أن يقوم بتحليل مرجتل. سأهل كبري التنفيذيني اريك مشدت مازحا عن "أكرث الطرق فعالية لفرز مليون من الاعداد الصحيحة 32 بت" عىل ما يبدو أن أحد ما غشش أوابما لنه أجاب برسعة "أعتقد أن فرز الفقاعة س يكون الطريقة اخلطأ أيضا" أىظر:.http://www.youtube.com/watch?v=k4RRi_ntQc8 1 ( اكنت تكل اجابة حصيحة: فرز الفقاعة من انحية املفهوم بس يط لكنه بطيء يف حاةل مجموعات البياانت الضخمة. اجلواب اذلي اكن يتوقعه مشدت رمبا اكن "خوارزمية فرز الرت ا.ت ب" 1.http://en.wikipedia.org/wiki/Radix_sort الهدف من حتليل اخلوارزميات هو املقارنة ذات املغزى بني اخلوارزميات لكن هناك بعض املشالك: قد يعمتد الداء النس يب للخوارزمية عىل خصائص احلاسوب )أو الاةل( فقد تكون خوارزمية ما أرسع عىل الاةل أ و خوارزمية أخرى أرسع عىل الاةل ب. احلل العام لهذه املشلكة هو حتديد الاةل المنوذج مث حتليل عدد اخلطوات أو العمليات اليت تتطلهبا اخلوارزمية حتت المنوذج املعطى. قد يعمتد الداء النسيب عىل تفاصيل مجموعة البياانت. مثال بعض خوارزميات الفرز تعمل أرسع ان اكنت البياانت مفروزة جزئيا خوارزميات أخرى تعمل أبطأ. الطريقة الشائعة لتجنب هذه املشلكة هو حتليل "سيناريو أسوأ احلالت". يفيد أحياان أن حنلل الداء عىل احلاةل املتوسطة ال أن هذا يف العادة أصعب و قد ل يكون واحضا أي حاةل ميكن أن تصنف مكتوسطة. يعمتد الداء النسيب أيضا عىل جحم املشلكة. خفوارزمية فرز رسيعة عىل القوامئ القصرية قد تصبح بطيئة عىل القوامئ الطويةل. الطريقة املعتادة للتعامل مع هذه املشلكة يه التعبري عن زمن التشغيل )أو عدد العمليات( اكقرتان حلجم املشلكة مث مقارنة الاقرتاانت ابملقاربة asymptotically لكام زاد جحم املشلكة. أظن أن أفضل اجابة لهذا السؤال يه "أفضل طريق لرتتيب مليون عدد حصيح يه اس تخدام أي طريقة فرز تعطيين اايها اللغة اليت أس تخدهما. فأداؤها مقبول ملعظم الغاايت و ان اكنت بطيئة سأس تخدم أداة لكتشاف موقع استنفاذ الوقت. ان ظهر بأن طريقة الفرز الرسع لها تأثري ملموس عىل الداء فسأحبث عن طريقة جيدة للفرز الرتتييب"(
فكر بايثون 194 اجليد يف هكذا مقارانت يه أهنا ميكن أن تس تخدم يف تبس يط تصنيف اخلوارزميات. مثال ان كن ت أعمل بأن زمن التشغيل للخوارزمية أ يتناسب مع جحم مدخالت قميته ن و زمن تشغيل اخلوارزمية ب يتناسب مع ن ٢ عندها ميكنين توقع أن تكون اخلوارزمية أ أرسع من ب لقمي ن الكبرية. يأيت هذا النوع من التحاليل مع بعض التحذير لكننا س نأيت عىل هذا فامي بعد. ب- 1 تراتب المنو أ افرتض أنك حللت خوارزميتان و عربت عن زمن التشغيل هلام حبجم املدخل: اخلوارزمية تأخذ 100 ن + 1 خطوة لتحل مسأةل حبجم ن اخلوارزمية ب تأخذ ن ٢ ن+ + 1 خطوة. اجلدول التايل يظهر زمن التشغيل لهذه اخلوارزميات لجحام خمتلفة من املسائل: جحم زمن التشغيل زمن التشغيل املدخالت ن للخوارزمية أ للخوارزمية ب 111 1001 10 10101 10001 100 1001001 100001 1000 >10 10 1000001 10000 عندما اكنت عندما اكنت ن = 10 ظهرت اخلوارزمية أ مبظهر سي فهيي تأخذ عرشة أضعاف الوقت اذلي تأخذه اخلوارزمية ب. لكن ن = 100 أصبحتا متساويتني تقريبا لكن للقمي الاكرب اكنت أ أفضل بكثري. السبب الرئييس هو أنه ن الك رية ب لقمي تكرب الاقرتاانت اليت حتتوي عىل ن احلد القائد term( )leading هو احلد اذلي أسه الكرب. ن ٢ عىل حنو أرسع من الاقرتان اذلي حده القائد اكن معامل احلد القائد يف اخلوارزمية عن املعامل س يكون هناك دامئا قمية لنون حيث أ كبري )100( ذلكل اكن أداء اخلوارزمية ب أفضل لقمي ن الصغرية. لكن بغض النظر أ ن 2 < ب ن. الربهان نفسه ينطبق عىل احلدود غري القائدة. حىت لو اكن زمن التشغيل للخوارزمية أ هو ن + 1000000 فس تظل أفضل من اخلوارزمية ب لقمي ن الكبرية كفاية. حنن يف العموم نتوقع من اخلوارزمية اليت لها حد قائد صغري أن تكون لها الافضلية يف املشالك الكبرية لكن للمشالك الصغرية فال بد و أن تكون هناك الشعرة اليت يكون عىل جانهبا الاخر أن اخلوارزمية الثانية يه الافضل. موقع هذه الشعرة يعمتد عىل تفاصيل اخلوارزمية و عىل املدخالت و كذكل عىل الاةل. و لهذا السبب هتمل يف غاايت حتليل اخلوارزميات. لكن ل يعين هذا أن عليك نس ياهنا.
فكر بايثون 195 ان اكن خلوارزميتني نفس احلد القائد فس يصعب القول أهيا أفضل مرة أخرى يعمتد القرار عىل التفاصيل. ذلا التحليل اخلوارزيم تعترب الاقرتاانت اليت لها نفس احلد القائد متاكفئة حىت و ان مل تكن لها نفس العوامل. و لغرض ترتيب المنو هو مجموعة من الاقرتاانت اليت يعترب سلوك منوها العري متاكفئا. مثال 2 ن و 100 ن و ن+ 1 لكها تنمتي اىل نفس تراتب المنو. و يكتب هكذا (n) O و غالبا ما تسمى "خطية" لن لك اقرتان يف املموعة يمنو خطيا بمنو n. تنمتي ل ) 2 O n) فهيي تربيعية )الامس اذلي يطلق عىل الاعداد اليت أسها 2(. لك الاقرتاانت ذات احلد القائد 2 n نرى يف اجلدول التايل بعض تراتيب المنو اليت تظهر بشلك شائع يف التحليل اخلوارزيم برتتيب تصاعدي من حيث السوء. االسم Order of growth O (1) Name ثابت constant لوغرتمي )ألي O (log b n) logarithmic (for any b) )b O (n) O (n log b n) O (n 2 ) O (n 3 ) خطي linear "en log en" "en log en" تربيعي quadratic تكعيبي cubic أسي )ألي O (c n ) exponential (for any c) )c ابلنس بة للحدود اللوغرمتية فأساس اللوغرمت ل هيم تغيري السس اكلرضب بثابت. و هو ل يغري تراتب المنو. و نفس المر ينطبق عىل الاقرتاانت الاس ية لك الاقرتاانت الاس ية تنمتي اىل نفس ترتيب المنو بغض النظر عن قاعدة الس. تمنو الاقرتاانت الاسية برسعة ذلكل فالقرتاانت الاسية مفيدة يف حل املشالك الصغرية فقط. مترين ب- 1 اقرأ صفحة ويكيبيداي عن Big-Oh عىل.http://en.wikipedia.org/wiki/Big_O_notation -1-2 -3-4 -5-6 مث أجب عن الاس ئةل التالية: ماهو ترتيب المنو ل n 3 + 2 n ماذا عن 1000000n 3 n+ 2 و عن n 3 + 1000000n 2 ماهو ترتيب المنو ل +n).(n+1) n ) 2 قبل أن تبأ ابلرضب تذكر أن لك ما حتتاجه هو احلد القائد. ان اكنت f يف (g) O لي اقرتان غري حمدد g ماذا نس تطيع القول عن af + b ان اكنت f1 و f2 يف (g) O ماذا نقول يف f1 + f2 ان اكنت f1 يف (g) O و f2 يف (h) O مفاذا نقول يف f1 + f2 ان اكنت f1 يف (g) O و f2 يف (h) O مفاذا نقول يف f1. f2 هذا النوع من التحليل غالبا ما جيده املربجمون اذلين هيمتون ابلداء عسريا عىل الهضم. و هلم بعض احلق يف ذكل: أحياان ل يفرق املعامل عن احلد غري القائد. فأحياان تكون تفاصيل الاةل و لغة الربجمة و خصائص املدخالت يه اليت تصنع الفرق الكرب. و للمشالك الصغرية فالسلوك التقاريب ليس ذا تأثري. لكن ان أبقيت هذه التحذير يف ابكل س يكون التحليل اخلوارزيم أداة مفيدة عىل الاقل للمشالك الكبرية. فاخلوارزميات "الفضل" يه يف الغالب "أفضل" و أحياان " أفضل بكثري". الفرق بني خوارزميتني جيدتني هلام نفس ترتيب المنو يكون يف العادة عامل اثبت لكن الفرق بني خوارزمية جيدة و خوارزمية سيئة ل يتسع هل ماكن!
ب- 2 حتليل معليات ابيثون الساس ية فكر بايثون 196 معظم العمليات احلسابية اثبتة الوقت الرضب يأخذ يف العادة وقتا أطول من امجلع و القسمة تأخذ وقتا أطول من لكهيام لكن زمن التشغيل هنا ل يعمتد عىل علو قمية العوامل. ي س تثىن من هذا الارقام الكبرية جدا فهناك يطول زمن التشغيل بزايدة عدد اخلاانت. معليات الفهرسة قراءة أو كتابة عنارص تسلسل أو قاموس أيضا اثبتة الوقت بغض النظر عن جحم هيلك البياانت. حلقة for اليت تدور يف تسلسل أو قاموس تكون يف العادة خطية طاملا اكنت لك العمليات يف منت احللقة اثبتة الوقت. مثال مض عنارص قامئة هو خطي: total = 0 for x in t: total += x الاقرتان اجلاهز sum خطي لنه يفعل نفس اليشء لكنه أرسع عىل حنو ما بسبب أنه تطبيق أكرث فعالية و يف لغة التحليل اخلواريم: هل معامل قائد أصغر. ان اس تخدمت نفس احللقة "لضافة" قامئة من انلارف فزمن التشغيل يكون تربيعي لن اضافة انلارف خطي. join طريقة أرسع لهنا خطية عىل مدى الطول اللكي للمحارف. ) n) O فان احللقة كلك تكون يف ) 1+a O. n) الاسثناء هو ان أثب ت أن احللقة تظل و حبمك اخلربة اذا اكن منت حلقة يف a O (n ) موجودة بعد عدد اثبت من التكرارات. ان اش تغلت احللقة عدد k من املرات بغض النظر عن n فاهنا تكون يف a حىت عندما تكون k كبرية. الرضب يف k ل يغري تراتب المنو لكن هذا ل خيتلف عن القسمة. ذلا فان اكن منت احللقة يف ) a O n) و اش تغلت عدد مرات يساوي n/k فاحللقة تكون يف ) 1+a O n) حىت ل k الكبرية. معظم معليات انلارف و التوبالت خطية لكن ان اكنت أطوال انلارف حمدودة بثابت اكلعمليات عىل حرف واحد فسوف تعترب اثبتة الوقت. معظم معليات القوامئ خطية ال هذه الاس تثناءات: اضافة عنرص يف هناية قامئة هو اثبت الوقت يف املتوسط عندما ل يظل متسعا فاهنا ت نسخ اىل موقع أكرب لكن الوقت الجاميل لعدد n من العمليات هو (n) O لهذا نقول ان الوقت انلفوظ )لسداد ادلين( imortized لعملية واحدة هو (1) O. حذف عنرص من هناية القامئة هو اثبت الوقت. الفرز هو n) O (n log معظم معليات القواميس و طرائقها اثبتة الوقت لكن هناك اس تثناءت أيضا: زمن التشغيل ل copy يتناسب مع عدد العنارص لكن ليس مع جحم العنارص )فهيي تنسخ مراجع و ليس العنارص نفسها(. وقت التشغيل ل update يتناسب مع جحم القاموس اذلي مرر كربمرت و ليس القاموس اذلي جيري حتديثه. Keys, values, items خطية لهنا ترجع قوامئ جديدة و Iterkeys و itervalues و
فكر بايثون 197 iteritems اثبتة الوقت لهنا ترجع تكرارات. لكن حلقة التكرارات فاحللقة تكون خطية. اس تخدام اقرتان iter خيفض بعض النفقات لكنه ل يغري تراتب المنو ال اذا اكن عدد العنارص اليت تعاجلها حمدد. أداء القواميس هو أحد معجزات علوم احلاسوب سرنى كيف تعمل يف القسم ب- 4. مترين ب- 2 اقرأ صفحة ويكيبيداي عن اخلوارزميات عىل http://en.wikipedia.org/wiki/sorting_algorithm مث أجب عن الاس ئةل التالية: ما هو "الفرز ابلقياس" ما يه أفضل أسوأ-حاةل ترتيب المنو للفرز ابلقياس ما يه أفضل أسوأ-حاةل ترتيب المنو 1- لي خوارزمية فرز 2- ما هو ترتيب المنو لفرز الفقاعة و ملاذا يظن ابراك أوابما بأهنا الطريقة اخلطأ ما هو ترتيب المنو لفرز الاساس ما يه الرشط املس بقة لس تعامهل 3- ما هو الفرز املس تقر و ملاذا هو همم معليا 4- ما يه أسوأ خوارزمية فرز )و يكون لها امس( 5- أي خوارزمية فرز تس تخدم مكتبة C و أي خوارزمية فرز تس تخدم مكتبة ابيثون هل هذه اخلوارزميات 6- مس تقرة قد تتطلب الالجابة منك أن تبحث يف جوجل. كثري من خوارزميات الفرز الالمقارن خطية اذن فلامذا يس تخدم ابيثون (n O(n log 7- ب- 3 حتليل خوارزميات البحث البحث هو خوارزمية تأخذ مجموعة و عنرص مس هتدف و تقرر فامي اذا اكن الهدف يف املموعة و غالبا ما ترجع املؤرش ذلكل الهدف. أبسط خوارزميات البحث يه "البحث اخلطي" و اذلي مير يف عنارص املموعة ابلرتتيب و يتوقف عندما جيد الهدف. و يف أسوأ احلالت فان عليه أن مير باكمل عنارص املموعة. و ذلكل فوقت التشغيل خطي. املؤثر in للتسلسالت يس تخدم حبثا خطيا و كذكل طرائق انلارف مثل find و.count ان اكنت العنارص مرتبة يف التسلسل ميكنك اس تخدام البحث التنصيفي و اذلي هو (n O. (log البحث التنصيفي شبيه ابلطريقة اليت تبحث هبا عن لكمة يف القاموس )احلقيقي و ليس هيلك البياانت(. فبدل من البدء من البداية و حفص لك عنرص ابلرتتيب تبدأ من املنتصف و ترى ان اكنت اللكمة اليت تبحث عهنا تأيت قبل أو بعد هذا املوقع. ان اكنت تأيت قبل فستبحث يف نصف النصف الاول. و ان اكنت بعد فستبحث يف نصف النصف الثاين. و أاي اكن موقعها فقد اخترصت نصف البحث املتبقي يف لك مرة. ان اكن يف التسلسل 1000000 عنرص س يأخذ اجياد اللكمة منك 20 خطوة أو اثبات عدم وجودها. هذا يعين 50000 مرة أرسع من البحث اخلطي. مترين ب- 3 أكتب اقرتاان امسه اكنت موجودة أو يرجع None ان مل تكن. bisection أو ميكنك قراءة واثئق مديول bisection و اس تخدامه! يأخذ قامئة مفروزة و قمية مس هتدفة و يرجع املؤرش لتكل القمية يف القامئة ان ميكن للبحث التنصيفي أن يكون أرسع بكثري من البحث اخلطي لكنه يتطلب كون التسلسل مرتبا و هو ما يتطلب هجدا اضافيا.
فكر بايثون 198 هناك نوع اخر من هيالك البياانت تسمى تقطيعية hashtable و يه أرسع من البحث التصنيفي تس تطيع القيام ابلبحث يف وقت اثبت و ل تتطلب من العنارص أن تكون مرتبة. قواميس ابيثون مطبقة ابس تخدام hashtables و هو السبب اذلي جعل لك معليات القواميس و من مضهنا مؤثر in اثبتة الوقت. جداول التقطيع ب- 4 Hashtables لرشح كيف تعمل جداول التقطيع و ملاذا اكن أداؤها هبذه اجلودة سأبدأ بتطبيق بس يط خلارطة مث أحس هنا تدرجييا اىل أن يصبح التطبيق تقطيعيا. سأس تخدم ابيثون لرشح هذه التطبيقات لكنك لن تكتب نصا كهذا يف ابيثون يف احلياة الواقعية ستس تعمل القاموس فقط! ذلكل و لهناية هذه الفصل حاول أن تتخيل بأن القواميس غري موجودة و أنك تريد تطبيق هيلك للبياانت يوصل بني املفاتيح و القمي. العمليات اليت س تطبقها يه: d[k] هذه العملية تكتب d يف قاموس ابيثون v. اىل القمية k أضف عنرصا جديدا يوصل من املفتاح :Add(k, (v.= v :Get(target) تبحث عن القمية اليت تقابل املفتاح key و ترجعها. لقاموس ابيثون d.d.get(target) أو d[target] تكتب هذه العملية هكذا سأفرتض مؤقتا بأن لك مفتاح يظهر مرة واحدة. أبسط تطبيق لهذه الواهجة هو اس تخدام قامئة من التوبل يكون لك توبل زوجني من املفتاح-القمية. class LinearMap(object): def init (self): self.items = [] def add(self, k, v): self.items.append((k, v)) def get(self, k): for key, val in self.items: if key == k: return val raise KeyError تضيف add توبل مفتاح-قمية لقامئة العنارص و هو ما يأخذ وقتا اثبتا. تس تخدم get حلقة for للبحث يف القامئة: فان وجدت املفتاح املس هتدف سرتجع القمية املقابةل هل و ال فس تصدر.KeyError اذن ف get خطية. هناك بديل هو ابقاء القامئة مفروزة حسب املفتاح. عندها تس تطيع get اس تخدام البحث التنصيفي و اذلي هو O.(logn) لكن ادراج عنرص جديد يف وسط قامئة خطي ذلكل فقد ل يكون هذا هو احلل الامثل. هناك هيالك بياانت أخرى )أنظر: ).http://en.wikipedia.org/wiki/red-black_tree time لكن هذا أيضا ليس جبودة اثبتات الوقت اذن لنتابع. get و add تطبق يف log
فكر بايثون 199 طريقة أخرى لتحسني LinearMap يه تفتيت قامئة أزواج املفتاح-القمية اىل قوامئ أصغر. هاك تطبيق امسه BetterMap و هو قامئة من 100 توصيل خطي.LinearMap سرنى حال بأن ترتيب المنو ل get ل زال خطيا لكن BetterMap يه خطوة عىل طريق جداول التقطيع: class BetterMap(object): def init (self, n=100): self.maps = [] for i in range(n): self.maps.append(linearmap()) def find_map(self, k): index = hash(k) % len(self.maps) return self.maps[index] def add(self, k, v): m = self.find_map(k) m.add(k, v) def get(self, k): m = self.find_map(k) return m.get(k) توجد init find_map ستبحث. قامئة من LinearMap عددها n. ت س تخدم من قبل add و get لتقرر يف أي توصيل س يوضع العنرص اجلديد أو يف أي توصيل تس تخدم find_map الاقرتان اجلاهز hash و اذلي يأخذ أي اكئن ابيثوين و حيوهل لعدد حصيح. هذه العملية لها حمدودية و يه أهنا تعمل مع املفاتيح التقطيعية. الامناط املتبدةل اكلقواميس و القوامئ غري تقطيعية. الاكئنات التقطيعية اليت تعترب متاكفئة ترجع نفس قمية التقطيع لكن العكس ليس ابلرضورة حصيح: اكئنان خمتلفان قد يرجعا نفس قمية التقطيع. يس تخدم find_map مؤثر القسمة بدون ابيق للف قمي التقطيع يف جمال من صفر اىل len(self.maps) اذن فالنتيجة يه مؤرش قانوين يف القامئة. هذا يعين ابلطبع أن الكثري من القمي التقطيعية ستلف يف نفس املؤرش. لكن ان اكن اقرتان التقطيع يوزع الاش ياء ابلتساوي اىل حد ما )و هو ما مصمت اقرتاانت التقطيع لجهل( اذن ابماكننا توقع 100/ n عنرص يف لك.LinearMap و مبا أن زمن التشغيل ل LinearMap.get يتناسب مع عدد العنارص فميكننا توقع أن BetterMap أرسع مبئة مرة من.LinearMap ترتيب المنو ل يزال خطيا لكن املعامل القائد أصبح أصغر. ل بأس هبذه النتيجة لكن جداول التقطيع Hashtable لزالت أفضل. هنا )أخريا( فكرة حامسة جتعل جداول التقطيع أرسع: ان أمكنك ابقاء أطوال LinearMap مضن اطار حمدد س تكون LinearMap.get اثبتة الوقت. لك ما عليك فعهل هو متابعة عدد العنارصة و عندما يتجاوز عتبة حتددها غري جحم جدول التقطيع ابضافة مزيد من.LinearMap هنا تطبيق جلدول تقطيع:
فكر بايثون 200 لك HashMap حتتوي عىل سيتابع عدد العنارص. class HashMap(object): def init (self): self.maps = BetterMap(2) self.num = 0 def get(self, k): return self.maps.get(k) def add(self, k, v): if self.num == len(self.maps.maps): self.resize() self.maps.add(k, v) self.num += 1 def resize(self): new_maps = BetterMap(self.num * 2) for m in self.maps.maps: for k, v in m.items: new_maps.add(k, v) self.maps = new_maps init تبدأ BetterMap ابثنتان من LinearMap اذلي num مث هتي يوفد get اىل. BetterMap الشغل احلقيقي س يقوم به add اذلي يتحقق من عدد العنارص و من جحم.resize يكون 1 اذن سينادي عىل LinearMap ان تساوا فان معدل عدد العنارص يف لك :BetterMap resize اجلديدة. تنشئ BetterMap جديدة بضعفي جحم السابقة مث "تعيد تقطيع" العنارص من اخلارطة من املهم اعادة التقطيع لن تغيري عدد ال LinearMap يغري مقام مؤثر القسمة بدون ابيق يف يعين بأن بعض الاكئنات اليت اكنت ملفوفة يف نفس ال LinearMap س تقسم )و هو ما أردانه أل توافق (. السابقة.find_map اىل هذا اعادة التقطيع خطية و عليه فان resize خطية و هو ما قد ل يبدو جيدا مبا أنين وعدت بأن add س تكون اثبتة الوقت. لكن تذكر بأنه ليس علينا اعادة ضبط احلجم يف لك مرة اذن ف add اثبتة الوقت يف العموم و أحياان فقط خطية. مكية العمل اللكية لتشغيل add عدد n من املرات يتناسب مع n اذن متوسط الوقت للك add يصبح اثبت الوقت! ليك ترى كيف تعمل هذه فكر يف البدء جبدول تقطيع فارغ مث اضافة تسلسل من العنارص. سنبدأ ابثنتني LinearMap اذن فعملييت add الاولتني رسيعتني )لنه ل توجد حاجة لعادة ضبط احلجم(. لنقل أهنام تأخذا وحدة واحدة من الشغل للك مهنام. add التالية تتطلب اعادة ضبط احلجم اذن فعلينا اعادة تقطيع العنرصين الولني )لندعو هذا وحدتني اضافيتني من الشغل( مث أضف عنرصا اثلثا )وحدة شغل اثلثة(. اضافة العنرص التايل يلكفنا وحدة واحدة اذن فاململ حىت الان 6 مديولت من الشغل لربعة عنارص. ال add التالية تلكف 5 وحدات لكن الثالثة اليت تيل تلكف وحدة واحدة للك مهنا اذن فالجاميل هو 14 وحدة لول 8 معليات.add
فكر بايثون 201 س تلكف وحدة لول 16 الشلك ب- 1 : تلكفة جداول التقطيع ل add add التالية 9 وحدات لكن بعدها ميكننا اضافة 7 add.add قبل معلية ضبط احلجم التالية اذن املموع هو 30 بعد 32 معلية add س تكون التلكفة الاجاملية 64 وحدة و أمتىن الان أن المنط أصبح واحضا دليك. و بعد عدد n من add حيث n يه للقوة 2 سيصبح مجموع اللكفة هو 2-2n وحدة اذن مفتوسط الشغل ل add واحدة هو أقل من وحدتني. عندما تكون n للقوة 2 تكون أفضل احلالت لقمي أخرى ل n س يكون متوسط الشغل أعىل قليال لكن هذا ليس بذي أمهية. املهم هو أهنا (1) O. الشلك ب- 1 يوحض كيف يعمل هذا الامر ابلرسوم. لك مربع ميثل وحدة شغل. الامعدة تبني الشغل اللكي للك ابلرتتيب من اليسار اىل الميني: معلييت add الولتني لكفتا وحدة واحدة الثالثة لكفت ثالث وحدات اخل. add معليات اعادة التقطيع الضافية تظهر كتسلسل من الابراج املتطاوةل و كذكل املتباعدة فامي بيهنا ابضطراد. الن ان هدمت البراج مسددا هبا تلكفة اعادة التقطيع اللكية سرتى ابلرمس أن التلكفة اللكية بعد عدد n من ال add هو 2-2n, لهذه اخلوارزمية خاصية هممة ويه أننا عندما نضبط جحم جدول التقطيع فانه يمنو مكتوالية هندس ية أي أننا نرضب احلجم بثابت. فان زدت احلجم حسابيا ابضافة عدد اثبت يف لك مرة س يكون متوسط الوقت للك add خطيا. ميكنك حتميل تطبيقي ل HashMap من http://thinkpython.org/code/map.py لكن تذكر بأنه ل يوجد ما يس تدعي اس تخدامه ان أردت التوصيل فاس تخدم قاموس ابيثون.
فكر بايثون 202 ج امللحق مليب Lumpy اس تخدمت عىل طول الكتاب رسومات لمتثيل حاةل برانمج شغال. يف القسم 2.2 اس تخدمنا رمس احلاةل لبيان أسامء و قمي املتغريات. و يف القسم 3.10 قدمت كل الرمس التستيفي اذلي يعرض اطارا واحدا للك نداء لقرتان. لك اطار يعرض الربمرت و املتغري انليل لالقرتان أو الطريقة. الرسوم التستيفية لالقرتاانت الجرتارية ظهرت يف القسمني 5.9 و 6.5. القسم 10.2 بني كيف تظهر القامئة يف رمس احلاةل و يف القسم 12.6 عرفنا طريقتني لمتثيل التوبل. القسم 15.2 قدم لنا رمس الاكئن و اذلي يظهر حاةل خصال اكئن و خصالها و خصال خصالها و هكذا القسم 15.3 اك فيه رسوم الاكئن للمس تطيالت و نقاطها املضمنة. القسم 16.1 بني احلاةل لاكئن.Time و يف القسم 18.2 اكن الرمس اذلي حيتوي عىل اكئن فئة و جتلية لك مهناممع خصالها. أخريا القسم 18.8 قدم رمس الفئة و اذلي أظهر الفئات اليت بين علهيا الربانمج و العالقات بيهنا. لك هذه الرسومات مبينية عىل "لغة المنذجة املوحدة" UML: Unified Modeling Language و يه لغة رسومية مقننة يس تخدهما همندسو احلاسوب للتواصل فامي بيهنم حول تصممي الربامج خصوصا الربامج اكئنية املنحى. UML لغة غنية مبختلف أشاكل الرسومات اليت متثل العديد من العالقات بني الاكئنات و الفئات. ما قدمته يف هذا الكتاب ما هو ال جزء يسري من هذه اللغة لكنه اكن اجلزء الكرث اس تعامل يف احلياة العملية. هدف هذا امللحق هو اس تعراض الرسومات يف الاقسام السابقة و تقدمي مليب. Lumpy مليب ( و يه اختصار ل UML Python مع تبديل م واقع بعض احلروف( يه جزء من سواميب اذلي س بق و ن صبته ان كنت قد معلت عىل دراسة احلاةل يف الفصل الرابع أو الفصل التاسع عرش أو ان معلت عىل المترين 15.4. يس تخدم مليب مديول ابيثون كذكل رسومات الفئات. inspect لفحص حاةل برانمج شغال و ليودل رسومات الاكئن )و مهنا الرمس التستيفي( و رمس احلاةل ج- 1 هنا مثال يس تخدم مليب لتوليد رمس حاةل
فكر بايثون 203 <module> n 17 message 'And now for something complete' pi 3.14159265359 الشلك ج- 1 رمس حاةل رمس مع مليب <module> countdown pi countdown countdown 2 pi 1 pi 0 الشلك ج- 2 رمس تستيفي from swampy.lumpy import Lumpy lumpy = Lumpy() lumpy.make_reference() message = 'And now for something completely different' n = 17 pi = 3.1415926535897932 lumpy.object_diagram() يس تورد السطر الول فئة مليب من.swampy.Lumpy ان مل يكن سواميب منصب كحزمة دليك فتأكد من أن ملفات سواميب موجود مسار حبث ابيثون و اس تخدم عبارة الاس ترياد التالية: from Lumpy import Lumpy مث تودل السطور التالية اكئن lumpy و توجد نقطة "مرجعية" مما يعين بأن مليب يسجل الاكئنات اليت عرفت حلد الان. يف التايل نعر ف متغريات جديدة و نس تدعي املرجعية هنا اكنت.message,,n pi object_diagram اذلي سريمس الاكئنات اليت مت تعريفها منذ النقطة الشلك ج- 1 يظهر النتيجة. خيتلف أسلوب الرمس عام أريتك اايه سابقا مثال هنا لك مرجع ممثل بدائرة ابلقرب من امس املتغري و خط يصل اىل القمية. و انلارف الكبرية مبتورة. لكن تظل املعلومات املس تقاة من الرمس نفسها. الاسامء العمومية موضوعة يف اطار ملصقه تدعى أيضا معومية. ميكنك حتميل هذا املثال من اضافة تعيينات أخرى و لحظ كيف سيبدو الرمس. <module> و هو يشري اىل أن هذه متغريات عىل مس توى املديول و.http://thinkpython.org/code/lumpy_demo1.py حاول الرمس التستيفي ج- 2 التايل هو مثال يس تخدم مليب لتوليد رمس تستيفي و ميكنك أيضا حتميهل من.http://thinkpython.org/code/lumpy_demo2.py
فكر بايثون 204 الشلك ج- 3 رمس الاكئن from swampy.lumpy import Lumpy def countdown(n): if n <= 0: print 'Blastoff!' lumpy.object_diagram() else: print n countdown(n-1) lumpy = Lumpy() lumpy.make_reference() countdown(3) الشلك ج- 2 يبني النتيجة. ميثل لك اطار بصندوق يكون امس الاقرتان خارجه و املتغري بداخهل. و مبا أن هذا الاقرتان اجرتاري يكون هناك اطار للك مرحةل من الجرتارات. تذكر بأن الرمس التستيفي يظهر حاةل الربانمج عند نقطة حمددة يف تنفيذه. و لتحصل عىل الرمس اذلي تريده أحياان عليك التفكري يف املاكن اذلي جيب أن تس تدعي object_diagram منه. و هنا اس تدعيت object_diagram مبارشة بعد تنفيذ احلاةل القاعدة لالجرتار و يف هذه احلاةل سرييين الرمس التستيفي لك مرحةل من مراحل الاجرتار. ميكنك اس تدعاء object_diagram أكرث من مرة لتحصل عىل لقطات من مراحل تنفيذ الربانمج. رسوم الاكئن ج- 3 هذا املثال يودل رمس اكئن يعرض القوامئ يف القسم 10.1. ميكنك حتميهل من.http://thinkpython.org/code/lumpy_demo3.py from swampy.lumpy import Lumpy lumpy = Lumpy() lumpy.make_reference() cheeses = ['Cheddar', 'Edam', 'Gouda']
فكر بايثون 205 الشلك ج- 4 : رمس الاكئن. numbers = [17, 123] empty = [] lumpy.object_diagram() الشلك ج- 3 يبني النتيجة. القوامئ ممثل بصناديق تظهر توصيل املؤرشات اىل العنارص. هذا المتثيل خادع قليال و ذكل لن املؤرشات ليست جزءا من القامئة يف احلقيقة لكنه يف رأيي جيعل الرمس أسهل للقراءة. القامئة الفارغة هنا متثل بصندوق فارغ. و هنا مثال يعرض القواميس من القسم 11.4.http://thinkpython.org/code/lumpy_demo4.py الشلك ج- 4. ميكنك حتميهل من from swampy.lumpy import Lumpy lumpy = Lumpy() lumpy.make_reference() hist = histogram('parrot') inverse = invert_dict(hist) lumpy.object_diagram() inverse يبني النتيجة. يصل القاموس hist بني احلروف )حمارف من حرف واحد( و بني العداد الصحيحة و يصل من الاعداد الصحيحة اىل قوامئ انلارف. و هذا املثال يودل رمس اكئن ل Point و.Rectangle كام يف القسم 15.6. ميكنك حتميهل من.http://thin;python.org/code/lumpy_demo5.py
فكر بايثون 206 الشلك ج- 5 : رمس الاكئن الشلك ج- 6 : رمس الاكئن import copy from swampy.lumpy import Lumpy lumpy = Lumpy() lumpy.make_reference() box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 box2 = copy.copy(box) lumpy.object_diagram() الشلك ج- 5 يظهر النتيجة. توجد copy.copy نسخة حضةل فيكون للك من box و box1 طوهل و عرضه اخلاص width و.height لكهنام يتشاراكن نفس اكئن Point املضمن. ل بأس هبذا النوع من التشارك عندما تكون الاكئنات غري متبدةل لكن للمناط املتبدةل فهو مصدر كبري للخطاء. ج- 4 اكئنات الاقرتاانت و الفئات عندما أس تخدم مليب لعمل رسوم الاكئنات فأان يف العادة أعر ف الاقرتاانت و الفئات قبل معل النقطة املرجعية. و هبذه الطريقة ل تظهر اكئنات الاقرتان و الفئة يف الرمس.